No empty .Rs/.Re
[netbsd-mini2440.git] / sys / arch / hp700 / dev / elroy.c
blob2bc64e348df8108ca781316770341f2f1f63c7af
1 /* $NetBSD: elroy.c,v 1.7 2009/05/07 15:34:49 skrll Exp $ */
3 /* $OpenBSD: elroy.c,v 1.5 2009/03/30 21:24:57 kettenis Exp $ */
5 /*
6 * Copyright (c) 2005 Michael Shalayeff
7 * All rights reserved.
9 * Permission to use, copy, modify, and distribute this software for any
10 * purpose with or without fee is hereby granted, provided that the above
11 * copyright notice and this permission notice appear in all copies.
13 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
14 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
16 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
18 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
19 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22 /* #include "cardbus.h" */
24 #include <sys/param.h>
25 #include <sys/systm.h>
26 #include <sys/device.h>
27 #include <sys/reboot.h>
28 #include <sys/malloc.h>
29 #include <sys/extent.h>
31 #include <machine/iomod.h>
32 #include <machine/autoconf.h>
34 #include <hp700/dev/cpudevs.h>
36 #if NCARDBUS > 0
37 #include <dev/cardbus/rbus.h>
38 #endif
40 #include <dev/pci/pcireg.h>
41 #include <dev/pci/pcivar.h>
42 #include <dev/pci/pcidevs.h>
44 #include <hp700/dev/elroyreg.h>
45 #include <hp700/dev/elroyvar.h>
47 #define ELROY_MEM_CHUNK 0x800000
48 #define ELROY_MEM_WINDOW (2 * ELROY_MEM_CHUNK)
50 int elroy_match(device_t, cfdata_t, void *);
51 void elroy_attach(device_t, device_t, void *);
53 CFATTACH_DECL_NEW(elroy, sizeof(struct elroy_softc), elroy_match, elroy_attach,
54 NULL, NULL);
56 extern struct cfdriver elroy_cd;
58 void elroy_write32(volatile uint32_t *, uint32_t);
59 uint32_t elroy_read32(volatile uint32_t *);
60 void elroy_attach_hook(device_t, device_t, struct pcibus_attach_args *);
61 int elroy_maxdevs(void *, int);
62 pcitag_t elroy_make_tag(void *, int, int, int);
63 void elroy_decompose_tag(void *, pcitag_t, int *, int *, int *);
64 pcireg_t elroy_conf_read(void *, pcitag_t, int);
65 void elroy_conf_write(void *, pcitag_t, int, pcireg_t);
67 int elroy_iomap(void *, bus_addr_t, bus_size_t, int, bus_space_handle_t *);
68 int elroy_memmap(void *, bus_addr_t, bus_size_t, int, bus_space_handle_t *);
69 int elroy_subregion(void *, bus_space_handle_t, bus_size_t, bus_size_t,
70 bus_space_handle_t *);
71 int elroy_ioalloc(void *, bus_addr_t, bus_addr_t, bus_size_t, bus_size_t,
72 bus_size_t, int, bus_addr_t *, bus_space_handle_t *);
73 int elroy_memalloc(void *, bus_addr_t, bus_addr_t, bus_size_t, bus_size_t,
74 bus_size_t, int, bus_addr_t *, bus_space_handle_t *);
75 void elroy_unmap(void *, bus_space_handle_t, bus_size_t);
76 void elroy_free(void *, bus_space_handle_t, bus_size_t);
77 void elroy_barrier(void *, bus_space_handle_t, bus_size_t, bus_size_t, int);
78 void *elroy_alloc_parent(device_t, struct pci_attach_args *, int);
79 void *elroy_vaddr(void *, bus_space_handle_t);
80 paddr_t elroy_mmap(void *, bus_addr_t, off_t, int, int);
82 uint8_t elroy_r1(void *, bus_space_handle_t, bus_size_t);
83 uint16_t elroy_r2(void *, bus_space_handle_t, bus_size_t);
84 uint32_t elroy_r4(void *, bus_space_handle_t, bus_size_t);
85 uint64_t elroy_r8(void *, bus_space_handle_t, bus_size_t);
86 void elroy_w1(void *, bus_space_handle_t, bus_size_t, uint8_t);
87 void elroy_w2(void *, bus_space_handle_t, bus_size_t, uint16_t);
88 void elroy_w4(void *, bus_space_handle_t, bus_size_t, uint32_t);
89 void elroy_w8(void *, bus_space_handle_t, bus_size_t, uint64_t);
91 void elroy_rm_1(void *, bus_space_handle_t, bus_size_t, uint8_t *,
92 bus_size_t);
93 void elroy_rm_2(void *, bus_space_handle_t, bus_size_t, uint16_t *,
94 bus_size_t);
95 void elroy_rm_4(void *, bus_space_handle_t, bus_size_t, uint32_t *,
96 bus_size_t);
97 void elroy_rm_8(void *, bus_space_handle_t, bus_size_t, uint64_t *,
98 bus_size_t);
99 void elroy_wm_1(void *, bus_space_handle_t, bus_size_t, const uint8_t *,
100 bus_size_t);
101 void elroy_wm_2(void *, bus_space_handle_t, bus_size_t, const uint16_t *,
102 bus_size_t);
103 void elroy_wm_4(void *, bus_space_handle_t, bus_size_t, const uint32_t *,
104 bus_size_t);
105 void elroy_wm_8(void *, bus_space_handle_t, bus_size_t, const uint64_t *,
106 bus_size_t);
107 void elroy_sm_1(void *, bus_space_handle_t, bus_size_t, uint8_t,
108 bus_size_t);
109 void elroy_sm_2(void *, bus_space_handle_t, bus_size_t, uint16_t,
110 bus_size_t);
111 void elroy_sm_4(void *, bus_space_handle_t, bus_size_t, uint32_t,
112 bus_size_t);
113 void elroy_sm_8(void *, bus_space_handle_t, bus_size_t, uint64_t,
114 bus_size_t);
116 void elroy_rrm_2(void *, bus_space_handle_t, bus_size_t, uint16_t *,
117 bus_size_t);
118 void elroy_rrm_4(void *, bus_space_handle_t, bus_size_t, uint32_t *,
119 bus_size_t);
120 void elroy_rrm_8(void *, bus_space_handle_t, bus_size_t, uint64_t *,
121 bus_size_t);
122 void elroy_wrm_2(void *, bus_space_handle_t, bus_size_t, const uint16_t *,
123 bus_size_t);
124 void elroy_wrm_4(void *, bus_space_handle_t, bus_size_t, const uint32_t *,
125 bus_size_t);
126 void elroy_wrm_8(void *, bus_space_handle_t, bus_size_t, const uint64_t *,
127 bus_size_t);
128 void elroy_rr_1(void *, bus_space_handle_t, bus_size_t, uint8_t *,
129 bus_size_t);
130 void elroy_rr_2(void *, bus_space_handle_t, bus_size_t, uint16_t *,
131 bus_size_t);
132 void elroy_rr_4(void *, bus_space_handle_t, bus_size_t, uint32_t *,
133 bus_size_t);
134 void elroy_rr_8(void *, bus_space_handle_t, bus_size_t, uint64_t *,
135 bus_size_t);
136 void elroy_wr_1(void *, bus_space_handle_t, bus_size_t, const uint8_t *,
137 bus_size_t);
138 void elroy_wr_2(void *, bus_space_handle_t, bus_size_t, const uint16_t *,
139 bus_size_t);
140 void elroy_wr_4(void *, bus_space_handle_t, bus_size_t, const uint32_t *,
141 bus_size_t);
142 void elroy_wr_8(void *, bus_space_handle_t, bus_size_t, const uint64_t *,
143 bus_size_t);
145 void elroy_rrr_2(void *, bus_space_handle_t, bus_size_t, uint16_t *,
146 bus_size_t);
147 void elroy_rrr_4(void *, bus_space_handle_t, bus_size_t, uint32_t *,
148 bus_size_t);
149 void elroy_rrr_8(void *, bus_space_handle_t, bus_size_t, uint64_t *,
150 bus_size_t);
151 void elroy_wrr_2(void *, bus_space_handle_t, bus_size_t, const uint16_t *,
152 bus_size_t);
153 void elroy_wrr_4(void *, bus_space_handle_t, bus_size_t, const uint32_t *,
154 bus_size_t);
155 void elroy_wrr_8(void *, bus_space_handle_t, bus_size_t, const uint64_t *,
156 bus_size_t);
157 void elroy_sr_1(void *, bus_space_handle_t, bus_size_t, uint8_t,
158 bus_size_t);
159 void elroy_sr_2(void *, bus_space_handle_t, bus_size_t, uint16_t,
160 bus_size_t);
161 void elroy_sr_4(void *, bus_space_handle_t, bus_size_t, uint32_t,
162 bus_size_t);
163 void elroy_sr_8(void *, bus_space_handle_t, bus_size_t, uint64_t,
164 bus_size_t);
165 void elroy_cp_1(void *, bus_space_handle_t, bus_size_t, bus_space_handle_t,
166 bus_size_t, bus_size_t);
167 void elroy_cp_2(void *, bus_space_handle_t, bus_size_t, bus_space_handle_t,
168 bus_size_t, bus_size_t);
169 void elroy_cp_4(void *, bus_space_handle_t, bus_size_t, bus_space_handle_t,
170 bus_size_t, bus_size_t);
171 void elroy_cp_8(void *, bus_space_handle_t, bus_size_t, bus_space_handle_t,
172 bus_size_t, bus_size_t);
174 int elroy_dmamap_create(void *, bus_size_t, int, bus_size_t, bus_size_t,
175 int, bus_dmamap_t *);
176 void elroy_dmamap_destroy(void *, bus_dmamap_t);
177 int elroy_dmamap_load(void *, bus_dmamap_t, void *, bus_size_t,
178 struct proc *, int);
179 int elroy_dmamap_load_mbuf(void *, bus_dmamap_t, struct mbuf *, int);
180 int elroy_dmamap_load_uio(void *, bus_dmamap_t, struct uio *, int);
181 int elroy_dmamap_load_raw(void *, bus_dmamap_t, bus_dma_segment_t *,
182 int, bus_size_t, int);
183 void elroy_dmamap_unload(void *, bus_dmamap_t);
184 void elroy_dmamap_sync(void *, bus_dmamap_t, bus_addr_t, bus_size_t,
185 int);
186 int elroy_dmamem_alloc(void *, bus_size_t, bus_size_t, bus_size_t,
187 bus_dma_segment_t *, int, int *, int);
188 void elroy_dmamem_free(void *, bus_dma_segment_t *, int);
189 int elroy_dmamem_map(void *, bus_dma_segment_t *, int, size_t,
190 void **, int);
191 void elroy_dmamem_unmap(void *, void *, size_t);
192 paddr_t elroy_dmamem_mmap(void *, bus_dma_segment_t *, int, off_t,
193 int, int);
196 elroy_match(device_t parent, cfdata_t cf, void *aux)
198 struct confargs *ca = aux;
200 if ((ca->ca_name && !strcmp(ca->ca_name, "lba")) ||
201 (ca->ca_type.iodc_type == HPPA_TYPE_BRIDGE &&
202 ca->ca_type.iodc_sv_model == HPPA_BRIDGE_DINO &&
203 ca->ca_type.iodc_model == 0x78))
204 return (1);
206 return (0);
209 void
210 elroy_write32(volatile uint32_t *p, uint32_t v)
212 *p = v;
215 uint32_t
216 elroy_read32(volatile uint32_t *p)
218 return *p;
221 void
222 elroy_attach_hook(device_t parent, device_t self,
223 struct pcibus_attach_args *pba)
229 elroy_maxdevs(void *v, int bus)
231 return (32);
234 pcitag_t
235 elroy_make_tag(void *v, int bus, int dev, int func)
237 if (bus > 255 || dev > 31 || func > 7)
238 panic("elroy_make_tag: bad request");
240 return ((bus << 16) | (dev << 11) | (func << 8));
243 void
244 elroy_decompose_tag(void *v, pcitag_t tag, int *bus, int *dev, int *func)
246 *bus = (tag >> 16) & 0xff;
247 *dev = (tag >> 11) & 0x1f;
248 *func= (tag >> 8) & 0x07;
251 pcireg_t
252 elroy_conf_read(void *v, pcitag_t tag, int reg)
254 struct elroy_softc *sc = v;
255 volatile struct elroy_regs *r = sc->sc_regs;
256 uint32_t arb_mask, err_cfg, control;
257 pcireg_t data, data1;
259 /* printf("elroy_conf_read(%p, 0x%08x, 0x%x)", v, tag, reg); */
260 arb_mask = elroy_read32(&r->arb_mask);
261 err_cfg = elroy_read32(&r->err_cfg);
262 control = elroy_read32(&r->control);
263 if (!arb_mask)
264 elroy_write32(&r->arb_mask, htole32(ELROY_ARB_ENABLE));
265 elroy_write32(&r->err_cfg, err_cfg |
266 htole32(ELROY_ERRCFG_SMART | ELROY_ERRCFG_CM));
267 elroy_write32(&r->control, (control | htole32(ELROY_CONTROL_CE)) &
268 ~htole32(ELROY_CONTROL_HF));
270 elroy_write32(&r->pci_conf_addr, htole32(tag | reg));
271 data1 = elroy_read32(&r->pci_conf_addr);
272 data = elroy_read32(&r->pci_conf_data);
274 elroy_write32(&r->control, control |
275 htole32(ELROY_CONTROL_CE|ELROY_CONTROL_CL));
276 elroy_write32(&r->control, control);
277 elroy_write32(&r->err_cfg, err_cfg);
278 if (!arb_mask)
279 elroy_write32(&r->arb_mask, arb_mask);
281 data = le32toh(data);
282 /* printf("=0x%08x (@ 0x%08x)\n", data, le32toh(data1)); */
283 return (data);
286 void
287 elroy_conf_write(void *v, pcitag_t tag, int reg, pcireg_t data)
289 struct elroy_softc *sc = v;
290 volatile struct elroy_regs *r = sc->sc_regs;
291 uint32_t arb_mask, err_cfg, control;
292 pcireg_t data1;
294 /* printf("elroy_conf_write(%p, 0x%08x, 0x%x, 0x%x)\n", v, tag, reg, data); */
295 arb_mask = elroy_read32(&r->arb_mask);
296 err_cfg = elroy_read32(&r->err_cfg);
297 control = elroy_read32(&r->control);
298 if (!arb_mask)
299 elroy_write32(&r->arb_mask, htole32(ELROY_ARB_ENABLE));
300 elroy_write32(&r->err_cfg, err_cfg |
301 htole32(ELROY_ERRCFG_SMART | ELROY_ERRCFG_CM));
302 elroy_write32(&r->control, (control | htole32(ELROY_CONTROL_CE)) &
303 ~htole32(ELROY_CONTROL_HF));
305 /* fix coalescing config writes errata by interleaving w/ a read */
306 elroy_write32(&r->pci_conf_addr, htole32(tag | PCI_ID_REG));
307 data1 = elroy_read32(&r->pci_conf_addr);
308 data1 = elroy_read32(&r->pci_conf_data);
310 elroy_write32(&r->pci_conf_addr, htole32(tag | reg));
311 data1 = elroy_read32(&r->pci_conf_addr);
312 elroy_write32(&r->pci_conf_data, htole32(data));
313 data1 = elroy_read32(&r->pci_conf_addr);
315 elroy_write32(&r->control, control |
316 htole32(ELROY_CONTROL_CE|ELROY_CONTROL_CL));
317 elroy_write32(&r->control, control);
318 elroy_write32(&r->err_cfg, err_cfg);
319 if (!arb_mask)
320 elroy_write32(&r->arb_mask, arb_mask);
324 elroy_iomap(void *v, bus_addr_t bpa, bus_size_t size,
325 int flags, bus_space_handle_t *bshp)
327 struct elroy_softc *sc = v;
328 /* volatile struct elroy_regs *r = sc->sc_regs; */
329 int error;
331 if ((error = bus_space_map(sc->sc_bt, bpa + sc->sc_iobase, size,
332 flags, bshp)))
333 return (error);
335 return (0);
339 elroy_memmap(void *v, bus_addr_t bpa, bus_size_t size,
340 int flags, bus_space_handle_t *bshp)
342 struct elroy_softc *sc = v;
343 /* volatile struct elroy_regs *r = sc->sc_regs; */
344 int error;
346 if ((error = bus_space_map(sc->sc_bt, bpa, size, flags, bshp)))
347 return (error);
349 return (0);
353 elroy_subregion(void *v, bus_space_handle_t bsh, bus_size_t offset,
354 bus_size_t size, bus_space_handle_t *nbshp)
356 *nbshp = bsh + offset;
357 return (0);
361 elroy_ioalloc(void *v, bus_addr_t rstart, bus_addr_t rend, bus_size_t size,
362 bus_size_t align, bus_size_t boundary, int flags, bus_addr_t *addrp,
363 bus_space_handle_t *bshp)
365 struct elroy_softc *sc = v;
366 volatile struct elroy_regs *r = sc->sc_regs;
367 bus_addr_t iostart, ioend;
369 iostart = r->io_base & ~htole32(ELROY_BASE_RE);
370 ioend = iostart + ~htole32(r->io_mask) + 1;
371 if (rstart < iostart || rend > ioend)
372 panic("elroy_ioalloc: bad region start/end");
374 rstart += sc->sc_iobase;
375 rend += sc->sc_iobase;
376 if (bus_space_alloc(sc->sc_bt, rstart, rend, size,
377 align, boundary, flags, addrp, bshp))
378 return (ENOMEM);
380 return (0);
384 elroy_memalloc(void *v, bus_addr_t rstart, bus_addr_t rend, bus_size_t size,
385 bus_size_t align, bus_size_t boundary, int flags, bus_addr_t *addrp,
386 bus_space_handle_t *bshp)
388 struct elroy_softc *sc = v;
389 /* volatile struct elroy_regs *r = sc->sc_regs; */
391 if (bus_space_alloc(sc->sc_bt, rstart, rend, size,
392 align, boundary, flags, addrp, bshp))
393 return (ENOMEM);
395 return (0);
398 void
399 elroy_unmap(void *v, bus_space_handle_t bsh, bus_size_t size)
401 struct elroy_softc *sc = v;
403 bus_space_free(sc->sc_bt, bsh, size);
406 void
407 elroy_free(void *v, bus_space_handle_t bh, bus_size_t size)
409 /* should be enough */
410 elroy_unmap(v, bh, size);
413 void
414 elroy_barrier(void *v, bus_space_handle_t h, bus_size_t o, bus_size_t l, int op)
416 struct elroy_softc *sc = v;
417 volatile struct elroy_regs *r = sc->sc_regs;
418 uint32_t data;
420 sync_caches();
421 if (op & BUS_SPACE_BARRIER_WRITE) {
422 data = r->pci_id; /* flush write fifo */
423 sync_caches();
427 #if NCARDBUS > 0
428 void *
429 elroy_alloc_parent(device_t self, struct pci_attach_args *pa, int io)
431 #if 0 /* TODO */
433 struct elroy_softc *sc = pa->pa_pc->_cookie;
434 struct extent *ex;
435 bus_space_tag_t tag;
436 bus_addr_t start;
437 bus_size_t size;
439 if (io) {
440 ex = sc->sc_ioex;
441 tag = pa->pa_iot;
442 start = 0xa000;
443 size = 0x1000;
444 } else {
445 if (!sc->sc_memex) {
446 bus_space_handle_t memh;
447 bus_addr_t mem_start;
449 if (elroy_memalloc(sc, 0xf0800000, 0xff7fffff,
450 ELROY_MEM_WINDOW, ELROY_MEM_WINDOW, EX_NOBOUNDARY,
451 0, &mem_start, &memh))
452 return (NULL);
454 snprintf(sc->sc_memexname, sizeof(sc->sc_memexname),
455 "%s_mem", sc->sc_dv.dv_xname);
456 if ((sc->sc_memex = extent_create(sc->sc_memexname,
457 mem_start, mem_start + ELROY_MEM_WINDOW, M_DEVBUF,
458 NULL, 0, EX_NOWAIT | EX_MALLOCOK)) == NULL) {
459 extent_destroy(sc->sc_ioex);
460 bus_space_free(sc->sc_bt, memh,
461 ELROY_MEM_WINDOW);
462 return (NULL);
465 ex = sc->sc_memex;
466 tag = pa->pa_memt;
467 start = ex->ex_start;
468 size = ELROY_MEM_CHUNK;
471 if (extent_alloc_subregion(ex, start, ex->ex_end, size, size, 0,
472 EX_NOBOUNDARY, EX_NOWAIT, &start))
473 return (NULL);
475 extent_free(ex, start, size, EX_NOWAIT);
476 return rbus_new_root_share(tag, ex, start, size, 0);
477 #else
478 return (NULL);
479 #endif
481 #endif
483 void *
484 elroy_vaddr(void *v, bus_space_handle_t h)
486 return ((void *)h);
489 paddr_t
490 elroy_mmap(void *v, bus_addr_t addr, off_t off, int prot, int flags)
493 return -1;
496 uint8_t
497 elroy_r1(void *v, bus_space_handle_t h, bus_size_t o)
499 h += o;
500 return *(volatile uint8_t *)h;
503 uint16_t
504 elroy_r2(void *v, bus_space_handle_t h, bus_size_t o)
506 volatile uint16_t *p;
508 h += o;
509 p = (volatile uint16_t *)h;
510 return (le16toh(*p));
513 uint32_t
514 elroy_r4(void *v, bus_space_handle_t h, bus_size_t o)
516 uint32_t data;
518 h += o;
519 data = *(volatile uint32_t *)h;
520 return (le32toh(data));
523 uint64_t
524 elroy_r8(void *v, bus_space_handle_t h, bus_size_t o)
526 uint64_t data;
528 h += o;
529 data = *(volatile uint64_t *)h;
530 return (le64toh(data));
533 void
534 elroy_w1(void *v, bus_space_handle_t h, bus_size_t o, uint8_t vv)
536 h += o;
537 *(volatile uint8_t *)h = vv;
540 void
541 elroy_w2(void *v, bus_space_handle_t h, bus_size_t o, uint16_t vv)
543 volatile uint16_t *p;
545 h += o;
546 p = (volatile uint16_t *)h;
547 *p = htole16(vv);
550 void
551 elroy_w4(void *v, bus_space_handle_t h, bus_size_t o, uint32_t vv)
553 h += o;
554 vv = htole32(vv);
555 *(volatile uint32_t *)h = vv;
558 void
559 elroy_w8(void *v, bus_space_handle_t h, bus_size_t o, uint64_t vv)
561 h += o;
562 *(volatile uint64_t *)h = htole64(vv);
566 void
567 elroy_rm_1(void *v, bus_space_handle_t h, bus_size_t o, uint8_t *a, bus_size_t c)
569 volatile uint8_t *p;
571 h += o;
572 p = (volatile uint8_t *)h;
573 while (c--)
574 *a++ = *p;
577 void
578 elroy_rm_2(void *v, bus_space_handle_t h, bus_size_t o, uint16_t *a, bus_size_t c)
580 volatile uint16_t *p;
582 h += o;
583 p = (volatile uint16_t *)h;
584 while (c--)
585 *a++ = le16toh(*p);
588 void
589 elroy_rm_4(void *v, bus_space_handle_t h, bus_size_t o, uint32_t *a, bus_size_t c)
591 volatile uint32_t *p;
593 h += o;
594 p = (volatile uint32_t *)h;
595 while (c--)
596 *a++ = le32toh(*p);
599 void
600 elroy_rm_8(void *v, bus_space_handle_t h, bus_size_t o, uint64_t *a, bus_size_t c)
602 volatile uint64_t *p;
604 h += o;
605 p = (volatile uint64_t *)h;
606 while (c--)
607 *a++ = le64toh(*p);
610 void
611 elroy_wm_1(void *v, bus_space_handle_t h, bus_size_t o, const uint8_t *a, bus_size_t c)
613 volatile uint8_t *p;
615 h += o;
616 p = (volatile uint8_t *)h;
617 while (c--)
618 *p = *a++;
621 void
622 elroy_wm_2(void *v, bus_space_handle_t h, bus_size_t o, const uint16_t *a, bus_size_t c)
624 volatile uint16_t *p;
626 h += o;
627 p = (volatile uint16_t *)h;
628 while (c--)
629 *p = htole16(*a++);
632 void
633 elroy_wm_4(void *v, bus_space_handle_t h, bus_size_t o, const uint32_t *a, bus_size_t c)
635 volatile uint32_t *p;
637 h += o;
638 p = (volatile uint32_t *)h;
639 while (c--)
640 *p = htole32(*a++);
643 void
644 elroy_wm_8(void *v, bus_space_handle_t h, bus_size_t o, const uint64_t *a, bus_size_t c)
646 volatile uint64_t *p;
648 h += o;
649 p = (volatile uint64_t *)h;
650 while (c--)
651 *p = htole64(*a++);
654 void
655 elroy_sm_1(void *v, bus_space_handle_t h, bus_size_t o, uint8_t vv, bus_size_t c)
657 volatile uint8_t *p;
659 h += o;
660 p = (volatile uint8_t *)h;
661 while (c--)
662 *p = vv;
665 void
666 elroy_sm_2(void *v, bus_space_handle_t h, bus_size_t o, uint16_t vv, bus_size_t c)
668 volatile uint16_t *p;
670 h += o;
671 p = (volatile uint16_t *)h;
672 vv = htole16(vv);
673 while (c--)
674 *p = vv;
677 void
678 elroy_sm_4(void *v, bus_space_handle_t h, bus_size_t o, uint32_t vv, bus_size_t c)
680 volatile uint32_t *p;
682 h += o;
683 p = (volatile uint32_t *)h;
684 vv = htole32(vv);
685 while (c--)
686 *p = vv;
689 void
690 elroy_sm_8(void *v, bus_space_handle_t h, bus_size_t o, uint64_t vv, bus_size_t c)
692 volatile uint64_t *p;
694 h += o;
695 p = (volatile uint64_t *)h;
696 vv = htole64(vv);
697 while (c--)
698 *p = vv;
701 void
702 elroy_rrm_2(void *v, bus_space_handle_t h, bus_size_t o,
703 uint16_t *a, bus_size_t c)
705 volatile uint16_t *p, *q = a;
707 h += o;
708 p = (volatile uint16_t *)h;
709 c /= 2;
710 while (c--)
711 *q++ = *p;
714 void
715 elroy_rrm_4(void *v, bus_space_handle_t h, bus_size_t o,
716 uint32_t *a, bus_size_t c)
718 volatile uint32_t *p, *q = a;
720 h += o;
721 p = (volatile uint32_t *)h;
722 c /= 4;
723 while (c--)
724 *q++ = *p;
727 void
728 elroy_rrm_8(void *v, bus_space_handle_t h, bus_size_t o,
729 uint64_t *a, bus_size_t c)
731 volatile uint64_t *p, *q = a;
733 h += o;
734 p = (volatile uint64_t *)h;
735 c /= 8;
736 while (c--)
737 *q++ = *p;
740 void
741 elroy_wrm_2(void *v, bus_space_handle_t h, bus_size_t o,
742 const uint16_t *a, bus_size_t c)
744 volatile uint16_t *p;
745 const uint16_t *q = a;
747 h += o;
748 p = (volatile uint16_t *)h;
749 c /= 2;
750 while (c--)
751 *p = *q++;
754 void
755 elroy_wrm_4(void *v, bus_space_handle_t h, bus_size_t o,
756 const uint32_t *a, bus_size_t c)
758 volatile uint32_t *p;
759 const uint32_t *q = a;
761 h += o;
762 p = (volatile uint32_t *)h;
763 c /= 4;
764 while (c--)
765 *p = *q++;
768 void
769 elroy_wrm_8(void *v, bus_space_handle_t h, bus_size_t o,
770 const uint64_t *a, bus_size_t c)
772 volatile uint64_t *p;
773 const uint64_t *q = a;
775 h += o;
776 p = (volatile uint64_t *)h;
777 c /= 8;
778 while (c--)
779 *p = *q++;
782 void
783 elroy_rr_1(void *v, bus_space_handle_t h, bus_size_t o, uint8_t *a, bus_size_t c)
785 volatile uint8_t *p;
787 h += o;
788 p = (volatile uint8_t *)h;
789 while (c--)
790 *a++ = *p++;
793 void
794 elroy_rr_2(void *v, bus_space_handle_t h, bus_size_t o, uint16_t *a, bus_size_t c)
796 volatile uint16_t *p, data;
798 h += o;
799 p = (volatile uint16_t *)h;
800 while (c--) {
801 data = *p++;
802 *a++ = le16toh(data);
806 void
807 elroy_rr_4(void *v, bus_space_handle_t h, bus_size_t o, uint32_t *a, bus_size_t c)
809 volatile uint32_t *p, data;
811 h += o;
812 p = (volatile uint32_t *)h;
813 while (c--) {
814 data = *p++;
815 *a++ = le32toh(data);
819 void
820 elroy_rr_8(void *v, bus_space_handle_t h, bus_size_t o, uint64_t *a, bus_size_t c)
822 volatile uint64_t *p, data;
824 h += o;
825 p = (volatile uint64_t *)h;
826 while (c--) {
827 data = *p++;
828 *a++ = le64toh(data);
832 void
833 elroy_wr_1(void *v, bus_space_handle_t h, bus_size_t o, const uint8_t *a, bus_size_t c)
835 volatile uint8_t *p;
837 h += o;
838 p = (volatile uint8_t *)h;
839 while (c--)
840 *p++ = *a++;
843 void
844 elroy_wr_2(void *v, bus_space_handle_t h, bus_size_t o, const uint16_t *a, bus_size_t c)
846 volatile uint16_t *p, data;
848 h += o;
849 p = (volatile uint16_t *)h;
850 while (c--) {
851 data = *a++;
852 *p++ = htole16(data);
856 void
857 elroy_wr_4(void *v, bus_space_handle_t h, bus_size_t o, const uint32_t *a, bus_size_t c)
859 volatile uint32_t *p, data;
861 h += o;
862 p = (volatile uint32_t *)h;
863 while (c--) {
864 data = *a++;
865 *p++ = htole32(data);
869 void
870 elroy_wr_8(void *v, bus_space_handle_t h, bus_size_t o, const uint64_t *a, bus_size_t c)
872 volatile uint64_t *p, data;
874 h += o;
875 p = (volatile uint64_t *)h;
876 while (c--) {
877 data = *a++;
878 *p++ = htole64(data);
882 void
883 elroy_rrr_2(void *v, bus_space_handle_t h, bus_size_t o,
884 uint16_t *a, bus_size_t c)
886 volatile uint16_t *p, *q = a;
888 c /= 2;
889 h += o;
890 p = (volatile uint16_t *)h;
891 while (c--)
892 *q++ = *p++;
895 void
896 elroy_rrr_4(void *v, bus_space_handle_t h, bus_size_t o,
897 uint32_t *a, bus_size_t c)
899 volatile uint32_t *p, *q = a;
901 c /= 4;
902 h += o;
903 p = (volatile uint32_t *)h;
904 while (c--)
905 *q++ = *p++;
908 void
909 elroy_rrr_8(void *v, bus_space_handle_t h, bus_size_t o,
910 uint64_t *a, bus_size_t c)
912 volatile uint64_t *p, *q = a;
914 c /= 8;
915 h += o;
916 p = (volatile uint64_t *)h;
917 while (c--)
918 *q++ = *p++;
921 void
922 elroy_wrr_2(void *v, bus_space_handle_t h, bus_size_t o,
923 const uint16_t *a, bus_size_t c)
925 volatile uint16_t *p;
926 const uint16_t *q = a;
928 c /= 2;
929 h += o;
930 p = (volatile uint16_t *)h;
931 while (c--)
932 *p++ = *q++;
935 void
936 elroy_wrr_4(void *v, bus_space_handle_t h, bus_size_t o,
937 const uint32_t *a, bus_size_t c)
939 volatile uint32_t *p;
940 const uint32_t *q = a;
942 c /= 4;
943 h += o;
944 p = (volatile uint32_t *)h;
945 while (c--)
946 *p++ = *q++;
949 void
950 elroy_wrr_8(void *v, bus_space_handle_t h, bus_size_t o,
951 const uint64_t *a, bus_size_t c)
953 volatile uint64_t *p;
954 const uint64_t *q = a;
956 c /= 8;
957 h += o;
958 p = (volatile uint64_t *)h;
959 while (c--)
960 *p++ = *q++;
963 void
964 elroy_sr_1(void *v, bus_space_handle_t h, bus_size_t o, uint8_t vv, bus_size_t c)
966 volatile uint8_t *p;
968 h += o;
969 p = (volatile uint8_t *)h;
970 while (c--)
971 *p++ = vv;
974 void
975 elroy_sr_2(void *v, bus_space_handle_t h, bus_size_t o, uint16_t vv, bus_size_t c)
977 volatile uint16_t *p;
979 h += o;
980 vv = htole16(vv);
981 p = (volatile uint16_t *)h;
982 while (c--)
983 *p++ = vv;
986 void
987 elroy_sr_4(void *v, bus_space_handle_t h, bus_size_t o, uint32_t vv, bus_size_t c)
989 volatile uint32_t *p;
991 h += o;
992 vv = htole32(vv);
993 p = (volatile uint32_t *)h;
994 while (c--)
995 *p++ = vv;
998 void
999 elroy_sr_8(void *v, bus_space_handle_t h, bus_size_t o, uint64_t vv, bus_size_t c)
1001 volatile uint64_t *p;
1003 h += o;
1004 vv = htole64(vv);
1005 p = (volatile uint64_t *)h;
1006 while (c--)
1007 *p++ = vv;
1010 void
1011 elroy_cp_1(void *v, bus_space_handle_t h1, bus_size_t o1,
1012 bus_space_handle_t h2, bus_size_t o2, bus_size_t c)
1014 while (c--)
1015 elroy_w1(v, h1, o1++, elroy_r1(v, h2, o2++));
1018 void
1019 elroy_cp_2(void *v, bus_space_handle_t h1, bus_size_t o1,
1020 bus_space_handle_t h2, bus_size_t o2, bus_size_t c)
1022 while (c--) {
1023 elroy_w2(v, h1, o1, elroy_r2(v, h2, o2));
1024 o1 += 2;
1025 o2 += 2;
1029 void
1030 elroy_cp_4(void *v, bus_space_handle_t h1, bus_size_t o1,
1031 bus_space_handle_t h2, bus_size_t o2, bus_size_t c)
1033 while (c--) {
1034 elroy_w4(v, h1, o1, elroy_r4(v, h2, o2));
1035 o1 += 4;
1036 o2 += 4;
1040 void
1041 elroy_cp_8(void *v, bus_space_handle_t h1, bus_size_t o1,
1042 bus_space_handle_t h2, bus_size_t o2, bus_size_t c)
1044 while (c--) {
1045 elroy_w8(v, h1, o1, elroy_r8(v, h2, o2));
1046 o1 += 8;
1047 o2 += 8;
1051 const struct hppa_bus_space_tag elroy_iomemt = {
1052 NULL,
1054 NULL, elroy_unmap, elroy_subregion, NULL, elroy_free,
1055 elroy_barrier, elroy_vaddr, elroy_mmap,
1056 elroy_r1, elroy_r2, elroy_r4, elroy_r8,
1057 elroy_w1, elroy_w2, elroy_w4, elroy_w8,
1058 elroy_rm_1, elroy_rm_2, elroy_rm_4, elroy_rm_8,
1059 elroy_wm_1, elroy_wm_2, elroy_wm_4, elroy_wm_8,
1060 elroy_sm_1, elroy_sm_2, elroy_sm_4, elroy_sm_8,
1061 elroy_rrm_2, elroy_rrm_4, elroy_rrm_8,
1062 elroy_wrm_2, elroy_wrm_4, elroy_wrm_8,
1063 elroy_rr_1, elroy_rr_2, elroy_rr_4, elroy_rr_8,
1064 elroy_wr_1, elroy_wr_2, elroy_wr_4, elroy_wr_8,
1065 elroy_rrr_2, elroy_rrr_4, elroy_rrr_8,
1066 elroy_wrr_2, elroy_wrr_4, elroy_wrr_8,
1067 elroy_sr_1, elroy_sr_2, elroy_sr_4, elroy_sr_8,
1068 elroy_cp_1, elroy_cp_2, elroy_cp_4, elroy_cp_8
1072 elroy_dmamap_create(void *v, bus_size_t size, int nsegments,
1073 bus_size_t maxsegsz, bus_size_t boundary, int flags, bus_dmamap_t *dmamp)
1075 struct elroy_softc *sc = v;
1077 /* TODO check the addresses, boundary, enable dma */
1079 return (bus_dmamap_create(sc->sc_dmat, size, nsegments,
1080 maxsegsz, boundary, flags, dmamp));
1083 void
1084 elroy_dmamap_destroy(void *v, bus_dmamap_t map)
1086 struct elroy_softc *sc = v;
1088 bus_dmamap_destroy(sc->sc_dmat, map);
1092 elroy_dmamap_load(void *v, bus_dmamap_t map, void *addr, bus_size_t size,
1093 struct proc *p, int flags)
1095 struct elroy_softc *sc = v;
1097 return (bus_dmamap_load(sc->sc_dmat, map, addr, size, p, flags));
1101 elroy_dmamap_load_mbuf(void *v, bus_dmamap_t map, struct mbuf *m, int flags)
1103 struct elroy_softc *sc = v;
1105 return (bus_dmamap_load_mbuf(sc->sc_dmat, map, m, flags));
1109 elroy_dmamap_load_uio(void *v, bus_dmamap_t map, struct uio *uio, int flags)
1111 struct elroy_softc *sc = v;
1113 return (bus_dmamap_load_uio(sc->sc_dmat, map, uio, flags));
1117 elroy_dmamap_load_raw(void *v, bus_dmamap_t map, bus_dma_segment_t *segs,
1118 int nsegs, bus_size_t size, int flags)
1120 struct elroy_softc *sc = v;
1122 return (bus_dmamap_load_raw(sc->sc_dmat, map, segs, nsegs, size, flags));
1125 void
1126 elroy_dmamap_unload(void *v, bus_dmamap_t map)
1128 struct elroy_softc *sc = v;
1130 bus_dmamap_unload(sc->sc_dmat, map);
1133 void
1134 elroy_dmamap_sync(void *v, bus_dmamap_t map, bus_addr_t off,
1135 bus_size_t len, int ops)
1137 struct elroy_softc *sc = v;
1139 bus_dmamap_sync(sc->sc_dmat, map, off, len, ops);
1143 elroy_dmamem_alloc(void *v, bus_size_t size, bus_size_t alignment,
1144 bus_size_t boundary, bus_dma_segment_t *segs,
1145 int nsegs, int *rsegs, int flags)
1147 struct elroy_softc *sc = v;
1149 return (bus_dmamem_alloc(sc->sc_dmat, size, alignment, boundary,
1150 segs, nsegs, rsegs, flags));
1153 void
1154 elroy_dmamem_free(void *v, bus_dma_segment_t *segs, int nsegs)
1156 struct elroy_softc *sc = v;
1158 bus_dmamem_free(sc->sc_dmat, segs, nsegs);
1162 elroy_dmamem_map(void *v, bus_dma_segment_t *segs, int nsegs, size_t size,
1163 void **kvap, int flags)
1165 struct elroy_softc *sc = v;
1167 return (bus_dmamem_map(sc->sc_dmat, segs, nsegs, size, kvap, flags));
1170 void
1171 elroy_dmamem_unmap(void *v, void *kva, size_t size)
1173 struct elroy_softc *sc = v;
1175 bus_dmamem_unmap(sc->sc_dmat, kva, size);
1178 paddr_t
1179 elroy_dmamem_mmap(void *v, bus_dma_segment_t *segs, int nsegs, off_t off,
1180 int prot, int flags)
1182 struct elroy_softc *sc = v;
1184 return (bus_dmamem_mmap(sc->sc_dmat, segs, nsegs, off, prot, flags));
1187 const struct hppa_bus_dma_tag elroy_dmat = {
1188 NULL,
1189 elroy_dmamap_create, elroy_dmamap_destroy,
1190 elroy_dmamap_load, elroy_dmamap_load_mbuf,
1191 elroy_dmamap_load_uio, elroy_dmamap_load_raw,
1192 elroy_dmamap_unload, elroy_dmamap_sync,
1194 elroy_dmamem_alloc, elroy_dmamem_free, elroy_dmamem_map,
1195 elroy_dmamem_unmap, elroy_dmamem_mmap
1198 const struct hppa_pci_chipset_tag elroy_pc = {
1199 NULL,
1200 elroy_attach_hook, elroy_maxdevs, elroy_make_tag, elroy_decompose_tag,
1201 elroy_conf_read, elroy_conf_write,
1202 apic_intr_map, apic_intr_string,
1203 apic_intr_establish, apic_intr_disestablish,
1204 #if NCARDBUS > 0
1205 elroy_alloc_parent
1206 #else
1207 NULL
1208 #endif
1211 void
1212 elroy_attach(device_t parent, device_t self, void *aux)
1214 struct elroy_softc *sc = device_private(self);
1215 struct confargs *ca = (struct confargs *)aux;
1216 struct pcibus_attach_args pba;
1217 volatile struct elroy_regs *r;
1218 const char *p = NULL, *q;
1219 int i;
1221 sc->sc_dv = self;
1222 sc->sc_hpa = ca->ca_hpa;
1223 sc->sc_bt = ca->ca_iot;
1224 sc->sc_dmat = ca->ca_dmatag;
1225 if (bus_space_map(sc->sc_bt, ca->ca_hpa, ca->ca_hpasz, 0, &sc->sc_bh)) {
1226 aprint_error(": can't map space\n");
1227 return;
1230 sc->sc_regs = r = bus_space_vaddr(sc->sc_bt, sc->sc_bh);
1231 elroy_write32(&r->pci_cmdstat, htole32(PCI_COMMAND_IO_ENABLE |
1232 PCI_COMMAND_MEM_ENABLE | PCI_COMMAND_MASTER_ENABLE));
1234 elroy_write32(&r->control, elroy_read32(&r->control) &
1235 ~htole32(ELROY_CONTROL_RF));
1236 for (i = 5000; i-- &&
1237 elroy_read32(&r->status) & htole32(ELROY_STATUS_RC); DELAY(10));
1238 if (i < 0) {
1239 char buf[128]; /* XXXNH */
1241 snprintb(buf, sizeof(buf), ELROY_STATUS_BITS,
1242 htole32(r->status));
1243 aprint_error(": reset failed; status %s\n", buf);
1244 return;
1247 q = "";
1248 sc->sc_ver = PCI_REVISION(le32toh(elroy_read32(&r->pci_class)));
1249 switch ((ca->ca_type.iodc_model << 4) |
1250 (ca->ca_type.iodc_revision >> 4)) {
1251 case 0x782:
1252 p = "Elroy";
1253 switch (sc->sc_ver) {
1254 default:
1255 q = "+";
1256 case 5: sc->sc_ver = 0x40; break;
1257 case 4: sc->sc_ver = 0x30; break;
1258 case 3: sc->sc_ver = 0x22; break;
1259 case 2: sc->sc_ver = 0x21; break;
1260 case 1: sc->sc_ver = 0x20; break;
1261 case 0: sc->sc_ver = 0x10; break;
1263 break;
1265 case 0x783:
1266 p = "Mercury";
1267 break;
1269 case 0x784:
1270 p = "Quicksilver";
1271 break;
1273 default:
1274 p = "Mojo";
1275 break;
1278 aprint_normal(": %s TR%d.%d%s", p, sc->sc_ver >> 4, sc->sc_ver & 0xf, q);
1279 apic_attach(sc);
1280 aprint_normal("\n");
1282 elroy_write32(&r->imask, htole32(0xffffffff << 30));
1283 elroy_write32(&r->ibase, htole32(ELROY_BASE_RE));
1285 /* TODO reserve elroy's pci space ? */
1287 #if 0
1288 printf("lmm %llx/%llx gmm %llx/%llx wlm %llx/%llx wgm %llx/%llx io %llx/%llx eio %llx/%llx\n",
1289 le64toh(r->lmmio_base), le64toh(r->lmmio_mask),
1290 le64toh(r->gmmio_base), le64toh(r->gmmio_mask),
1291 le64toh(r->wlmmio_base), le64toh(r->wlmmio_mask),
1292 le64toh(r->wgmmio_base), le64toh(r->wgmmio_mask),
1293 le64toh(r->io_base), le64toh(r->io_mask),
1294 le64toh(r->eio_base), le64toh(r->eio_mask));
1295 #endif
1297 /* XXX evil hack! */
1298 sc->sc_iobase = 0xfee00000;
1300 sc->sc_iot = elroy_iomemt;
1301 sc->sc_iot.hbt_cookie = sc;
1302 sc->sc_iot.hbt_map = elroy_iomap;
1303 sc->sc_iot.hbt_alloc = elroy_ioalloc;
1304 sc->sc_memt = elroy_iomemt;
1305 sc->sc_memt.hbt_cookie = sc;
1306 sc->sc_memt.hbt_map = elroy_memmap;
1307 sc->sc_memt.hbt_alloc = elroy_memalloc;
1308 sc->sc_pc = elroy_pc;
1309 sc->sc_pc._cookie = sc;
1310 sc->sc_dmatag = elroy_dmat;
1311 sc->sc_dmatag._cookie = sc;
1313 memset(&pba, 0, sizeof(pba));
1314 pba.pba_iot = &sc->sc_iot;
1315 pba.pba_memt = &sc->sc_memt;
1316 pba.pba_dmat = &sc->sc_dmatag;
1317 pba.pba_pc = &sc->sc_pc;
1318 pba.pba_bus = 0; /* (le32toh(elroy_read32(&r->busnum)) & 0xff) >> 4; */
1319 pba.pba_flags = PCI_FLAGS_IO_ENABLED | PCI_FLAGS_MEM_ENABLED;
1321 config_found_ia(self, "pcibus", &pba, pcibusprint);