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 $ */
6 * Copyright (c) 2005 Michael Shalayeff
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>
37 #include <dev/cardbus/rbus.h>
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
,
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 *,
93 void elroy_rm_2(void *, bus_space_handle_t
, bus_size_t
, uint16_t *,
95 void elroy_rm_4(void *, bus_space_handle_t
, bus_size_t
, uint32_t *,
97 void elroy_rm_8(void *, bus_space_handle_t
, bus_size_t
, uint64_t *,
99 void elroy_wm_1(void *, bus_space_handle_t
, bus_size_t
, const uint8_t *,
101 void elroy_wm_2(void *, bus_space_handle_t
, bus_size_t
, const uint16_t *,
103 void elroy_wm_4(void *, bus_space_handle_t
, bus_size_t
, const uint32_t *,
105 void elroy_wm_8(void *, bus_space_handle_t
, bus_size_t
, const uint64_t *,
107 void elroy_sm_1(void *, bus_space_handle_t
, bus_size_t
, uint8_t,
109 void elroy_sm_2(void *, bus_space_handle_t
, bus_size_t
, uint16_t,
111 void elroy_sm_4(void *, bus_space_handle_t
, bus_size_t
, uint32_t,
113 void elroy_sm_8(void *, bus_space_handle_t
, bus_size_t
, uint64_t,
116 void elroy_rrm_2(void *, bus_space_handle_t
, bus_size_t
, uint16_t *,
118 void elroy_rrm_4(void *, bus_space_handle_t
, bus_size_t
, uint32_t *,
120 void elroy_rrm_8(void *, bus_space_handle_t
, bus_size_t
, uint64_t *,
122 void elroy_wrm_2(void *, bus_space_handle_t
, bus_size_t
, const uint16_t *,
124 void elroy_wrm_4(void *, bus_space_handle_t
, bus_size_t
, const uint32_t *,
126 void elroy_wrm_8(void *, bus_space_handle_t
, bus_size_t
, const uint64_t *,
128 void elroy_rr_1(void *, bus_space_handle_t
, bus_size_t
, uint8_t *,
130 void elroy_rr_2(void *, bus_space_handle_t
, bus_size_t
, uint16_t *,
132 void elroy_rr_4(void *, bus_space_handle_t
, bus_size_t
, uint32_t *,
134 void elroy_rr_8(void *, bus_space_handle_t
, bus_size_t
, uint64_t *,
136 void elroy_wr_1(void *, bus_space_handle_t
, bus_size_t
, const uint8_t *,
138 void elroy_wr_2(void *, bus_space_handle_t
, bus_size_t
, const uint16_t *,
140 void elroy_wr_4(void *, bus_space_handle_t
, bus_size_t
, const uint32_t *,
142 void elroy_wr_8(void *, bus_space_handle_t
, bus_size_t
, const uint64_t *,
145 void elroy_rrr_2(void *, bus_space_handle_t
, bus_size_t
, uint16_t *,
147 void elroy_rrr_4(void *, bus_space_handle_t
, bus_size_t
, uint32_t *,
149 void elroy_rrr_8(void *, bus_space_handle_t
, bus_size_t
, uint64_t *,
151 void elroy_wrr_2(void *, bus_space_handle_t
, bus_size_t
, const uint16_t *,
153 void elroy_wrr_4(void *, bus_space_handle_t
, bus_size_t
, const uint32_t *,
155 void elroy_wrr_8(void *, bus_space_handle_t
, bus_size_t
, const uint64_t *,
157 void elroy_sr_1(void *, bus_space_handle_t
, bus_size_t
, uint8_t,
159 void elroy_sr_2(void *, bus_space_handle_t
, bus_size_t
, uint16_t,
161 void elroy_sr_4(void *, bus_space_handle_t
, bus_size_t
, uint32_t,
163 void elroy_sr_8(void *, bus_space_handle_t
, bus_size_t
, uint64_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
,
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
,
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,
191 void elroy_dmamem_unmap(void *, void *, size_t);
192 paddr_t
elroy_dmamem_mmap(void *, bus_dma_segment_t
*, int, off_t
,
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))
210 elroy_write32(volatile uint32_t *p
, uint32_t v
)
216 elroy_read32(volatile uint32_t *p
)
222 elroy_attach_hook(device_t parent
, device_t self
,
223 struct pcibus_attach_args
*pba
)
229 elroy_maxdevs(void *v
, int bus
)
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));
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;
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
);
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
);
279 elroy_write32(&r
->arb_mask
, arb_mask
);
281 data
= le32toh(data
);
282 /* printf("=0x%08x (@ 0x%08x)\n", data, le32toh(data1)); */
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
;
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
);
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
);
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; */
331 if ((error
= bus_space_map(sc
->sc_bt
, bpa
+ sc
->sc_iobase
, size
,
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; */
346 if ((error
= bus_space_map(sc
->sc_bt
, bpa
, size
, flags
, bshp
)))
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
;
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
))
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
))
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
);
407 elroy_free(void *v
, bus_space_handle_t bh
, bus_size_t size
)
409 /* should be enough */
410 elroy_unmap(v
, bh
, size
);
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
;
421 if (op
& BUS_SPACE_BARRIER_WRITE
) {
422 data
= r
->pci_id
; /* flush write fifo */
429 elroy_alloc_parent(device_t self
, struct pci_attach_args
*pa
, int io
)
433 struct elroy_softc
*sc
= pa
->pa_pc
->_cookie
;
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
))
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
,
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
))
475 extent_free(ex
, start
, size
, EX_NOWAIT
);
476 return rbus_new_root_share(tag
, ex
, start
, size
, 0);
484 elroy_vaddr(void *v
, bus_space_handle_t h
)
490 elroy_mmap(void *v
, bus_addr_t addr
, off_t off
, int prot
, int flags
)
497 elroy_r1(void *v
, bus_space_handle_t h
, bus_size_t o
)
500 return *(volatile uint8_t *)h
;
504 elroy_r2(void *v
, bus_space_handle_t h
, bus_size_t o
)
506 volatile uint16_t *p
;
509 p
= (volatile uint16_t *)h
;
510 return (le16toh(*p
));
514 elroy_r4(void *v
, bus_space_handle_t h
, bus_size_t o
)
519 data
= *(volatile uint32_t *)h
;
520 return (le32toh(data
));
524 elroy_r8(void *v
, bus_space_handle_t h
, bus_size_t o
)
529 data
= *(volatile uint64_t *)h
;
530 return (le64toh(data
));
534 elroy_w1(void *v
, bus_space_handle_t h
, bus_size_t o
, uint8_t vv
)
537 *(volatile uint8_t *)h
= vv
;
541 elroy_w2(void *v
, bus_space_handle_t h
, bus_size_t o
, uint16_t vv
)
543 volatile uint16_t *p
;
546 p
= (volatile uint16_t *)h
;
551 elroy_w4(void *v
, bus_space_handle_t h
, bus_size_t o
, uint32_t vv
)
555 *(volatile uint32_t *)h
= vv
;
559 elroy_w8(void *v
, bus_space_handle_t h
, bus_size_t o
, uint64_t vv
)
562 *(volatile uint64_t *)h
= htole64(vv
);
567 elroy_rm_1(void *v
, bus_space_handle_t h
, bus_size_t o
, uint8_t *a
, bus_size_t c
)
572 p
= (volatile uint8_t *)h
;
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
;
583 p
= (volatile uint16_t *)h
;
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
;
594 p
= (volatile uint32_t *)h
;
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
;
605 p
= (volatile uint64_t *)h
;
611 elroy_wm_1(void *v
, bus_space_handle_t h
, bus_size_t o
, const uint8_t *a
, bus_size_t c
)
616 p
= (volatile uint8_t *)h
;
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
;
627 p
= (volatile uint16_t *)h
;
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
;
638 p
= (volatile uint32_t *)h
;
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
;
649 p
= (volatile uint64_t *)h
;
655 elroy_sm_1(void *v
, bus_space_handle_t h
, bus_size_t o
, uint8_t vv
, bus_size_t c
)
660 p
= (volatile uint8_t *)h
;
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
;
671 p
= (volatile uint16_t *)h
;
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
;
683 p
= (volatile uint32_t *)h
;
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
;
695 p
= (volatile uint64_t *)h
;
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
;
708 p
= (volatile uint16_t *)h
;
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
;
721 p
= (volatile uint32_t *)h
;
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
;
734 p
= (volatile uint64_t *)h
;
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
;
748 p
= (volatile uint16_t *)h
;
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
;
762 p
= (volatile uint32_t *)h
;
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
;
776 p
= (volatile uint64_t *)h
;
783 elroy_rr_1(void *v
, bus_space_handle_t h
, bus_size_t o
, uint8_t *a
, bus_size_t c
)
788 p
= (volatile uint8_t *)h
;
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
;
799 p
= (volatile uint16_t *)h
;
802 *a
++ = le16toh(data
);
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
;
812 p
= (volatile uint32_t *)h
;
815 *a
++ = le32toh(data
);
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
;
825 p
= (volatile uint64_t *)h
;
828 *a
++ = le64toh(data
);
833 elroy_wr_1(void *v
, bus_space_handle_t h
, bus_size_t o
, const uint8_t *a
, bus_size_t c
)
838 p
= (volatile uint8_t *)h
;
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
;
849 p
= (volatile uint16_t *)h
;
852 *p
++ = htole16(data
);
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
;
862 p
= (volatile uint32_t *)h
;
865 *p
++ = htole32(data
);
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
;
875 p
= (volatile uint64_t *)h
;
878 *p
++ = htole64(data
);
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
;
890 p
= (volatile uint16_t *)h
;
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
;
903 p
= (volatile uint32_t *)h
;
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
;
916 p
= (volatile uint64_t *)h
;
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
;
930 p
= (volatile uint16_t *)h
;
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
;
944 p
= (volatile uint32_t *)h
;
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
;
958 p
= (volatile uint64_t *)h
;
964 elroy_sr_1(void *v
, bus_space_handle_t h
, bus_size_t o
, uint8_t vv
, bus_size_t c
)
969 p
= (volatile uint8_t *)h
;
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
;
981 p
= (volatile uint16_t *)h
;
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
;
993 p
= (volatile uint32_t *)h
;
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
;
1005 p
= (volatile uint64_t *)h
;
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
)
1015 elroy_w1(v
, h1
, o1
++, elroy_r1(v
, h2
, o2
++));
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
)
1023 elroy_w2(v
, h1
, o1
, elroy_r2(v
, h2
, o2
));
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
)
1034 elroy_w4(v
, h1
, o1
, elroy_r4(v
, h2
, o2
));
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
)
1045 elroy_w8(v
, h1
, o1
, elroy_r8(v
, h2
, o2
));
1051 const struct hppa_bus_space_tag elroy_iomemt
= {
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
));
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
));
1126 elroy_dmamap_unload(void *v
, bus_dmamap_t map
)
1128 struct elroy_softc
*sc
= v
;
1130 bus_dmamap_unload(sc
->sc_dmat
, map
);
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
));
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
));
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
);
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
= {
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
= {
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
,
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
;
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");
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));
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
);
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)) {
1253 switch (sc
->sc_ver
) {
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;
1278 aprint_normal(": %s TR%d.%d%s", p
, sc
->sc_ver
>> 4, sc
->sc_ver
& 0xf, q
);
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 ? */
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
));
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
);