1 /* $NetBSD: elroy.c,v 1.1 2014/02/24 07:23:42 skrll Exp $ */ 2 3 /* $OpenBSD: elroy.c,v 1.5 2009/03/30 21:24:57 kettenis Exp $ */ 4 5 /* 6 * Copyright (c) 2005 Michael Shalayeff 7 * All rights reserved. 8 * 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. 12 * 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. 20 */ 21 22 /* #include "cardbus.h" */ 23 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> 30 31 #include <machine/iomod.h> 32 #include <machine/autoconf.h> 33 34 #include <hppa/dev/cpudevs.h> 35 36 #if NCARDBUS > 0 37 #include <dev/cardbus/rbus.h> 38 #endif 39 40 #include <dev/pci/pcireg.h> 41 #include <dev/pci/pcivar.h> 42 #include <dev/pci/pcidevs.h> 43 44 #include <hppa/dev/elroyreg.h> 45 #include <hppa/dev/elroyvar.h> 46 47 #define ELROY_MEM_CHUNK 0x800000 48 #define ELROY_MEM_WINDOW (2 * ELROY_MEM_CHUNK) 49 50 int elroy_match(device_t, cfdata_t, void *); 51 void elroy_attach(device_t, device_t, void *); 52 53 CFATTACH_DECL_NEW(elroy, sizeof(struct elroy_softc), elroy_match, elroy_attach, 54 NULL, NULL); 55 56 extern struct cfdriver elroy_cd; 57 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); 66 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); 81 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); 90 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); 115 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); 144 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); 173 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); 194 195 int 196 elroy_match(device_t parent, cfdata_t cf, void *aux) 197 { 198 struct confargs *ca = aux; 199 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); 205 206 return (0); 207 } 208 209 void 210 elroy_write32(volatile uint32_t *p, uint32_t v) 211 { 212 *p = v; 213 } 214 215 uint32_t 216 elroy_read32(volatile uint32_t *p) 217 { 218 return *p; 219 } 220 221 void 222 elroy_attach_hook(device_t parent, device_t self, 223 struct pcibus_attach_args *pba) 224 { 225 226 } 227 228 int 229 elroy_maxdevs(void *v, int bus) 230 { 231 return (32); 232 } 233 234 pcitag_t 235 elroy_make_tag(void *v, int bus, int dev, int func) 236 { 237 if (bus > 255 || dev > 31 || func > 7) 238 panic("elroy_make_tag: bad request"); 239 240 return ((bus << 16) | (dev << 11) | (func << 8)); 241 } 242 243 void 244 elroy_decompose_tag(void *v, pcitag_t tag, int *bus, int *dev, int *func) 245 { 246 *bus = (tag >> 16) & 0xff; 247 *dev = (tag >> 11) & 0x1f; 248 *func= (tag >> 8) & 0x07; 249 } 250 251 pcireg_t 252 elroy_conf_read(void *v, pcitag_t tag, int reg) 253 { 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; 258 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)); 269 270 elroy_write32(&r->pci_conf_addr, htole32(tag | reg)); 271 (void)elroy_read32(&r->pci_conf_addr); 272 data = elroy_read32(&r->pci_conf_data); 273 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); 280 281 data = le32toh(data); 282 /* printf("=0x%08x (@ 0x%08x)\n", data, le32toh(data1)); */ 283 return (data); 284 } 285 286 void 287 elroy_conf_write(void *v, pcitag_t tag, int reg, pcireg_t data) 288 { 289 struct elroy_softc *sc = v; 290 volatile struct elroy_regs *r = sc->sc_regs; 291 uint32_t arb_mask, err_cfg, control; 292 293 /* printf("elroy_conf_write(%p, 0x%08x, 0x%x, 0x%x)\n", v, tag, reg, data); */ 294 arb_mask = elroy_read32(&r->arb_mask); 295 err_cfg = elroy_read32(&r->err_cfg); 296 control = elroy_read32(&r->control); 297 if (!arb_mask) 298 elroy_write32(&r->arb_mask, htole32(ELROY_ARB_ENABLE)); 299 elroy_write32(&r->err_cfg, err_cfg | 300 htole32(ELROY_ERRCFG_SMART | ELROY_ERRCFG_CM)); 301 elroy_write32(&r->control, (control | htole32(ELROY_CONTROL_CE)) & 302 ~htole32(ELROY_CONTROL_HF)); 303 304 /* fix coalescing config writes errata by interleaving w/ a read */ 305 elroy_write32(&r->pci_conf_addr, htole32(tag | PCI_ID_REG)); 306 (void)elroy_read32(&r->pci_conf_addr); 307 (void)elroy_read32(&r->pci_conf_data); 308 309 elroy_write32(&r->pci_conf_addr, htole32(tag | reg)); 310 (void)elroy_read32(&r->pci_conf_addr); 311 elroy_write32(&r->pci_conf_data, htole32(data)); 312 (void)elroy_read32(&r->pci_conf_addr); 313 314 elroy_write32(&r->control, control | 315 htole32(ELROY_CONTROL_CE|ELROY_CONTROL_CL)); 316 elroy_write32(&r->control, control); 317 elroy_write32(&r->err_cfg, err_cfg); 318 if (!arb_mask) 319 elroy_write32(&r->arb_mask, arb_mask); 320 } 321 322 int 323 elroy_iomap(void *v, bus_addr_t bpa, bus_size_t size, 324 int flags, bus_space_handle_t *bshp) 325 { 326 struct elroy_softc *sc = v; 327 /* volatile struct elroy_regs *r = sc->sc_regs; */ 328 int error; 329 330 if ((error = bus_space_map(sc->sc_bt, bpa + sc->sc_iobase, size, 331 flags, bshp))) 332 return (error); 333 334 return (0); 335 } 336 337 int 338 elroy_memmap(void *v, bus_addr_t bpa, bus_size_t size, 339 int flags, bus_space_handle_t *bshp) 340 { 341 struct elroy_softc *sc = v; 342 /* volatile struct elroy_regs *r = sc->sc_regs; */ 343 int error; 344 345 if ((error = bus_space_map(sc->sc_bt, bpa, size, flags, bshp))) 346 return (error); 347 348 return (0); 349 } 350 351 int 352 elroy_subregion(void *v, bus_space_handle_t bsh, bus_size_t offset, 353 bus_size_t size, bus_space_handle_t *nbshp) 354 { 355 *nbshp = bsh + offset; 356 return (0); 357 } 358 359 int 360 elroy_ioalloc(void *v, bus_addr_t rstart, bus_addr_t rend, bus_size_t size, 361 bus_size_t align, bus_size_t boundary, int flags, bus_addr_t *addrp, 362 bus_space_handle_t *bshp) 363 { 364 struct elroy_softc *sc = v; 365 volatile struct elroy_regs *r = sc->sc_regs; 366 bus_addr_t iostart, ioend; 367 368 iostart = r->io_base & ~htole32(ELROY_BASE_RE); 369 ioend = iostart + ~htole32(r->io_mask) + 1; 370 if (rstart < iostart || rend > ioend) 371 panic("elroy_ioalloc: bad region start/end"); 372 373 rstart += sc->sc_iobase; 374 rend += sc->sc_iobase; 375 if (bus_space_alloc(sc->sc_bt, rstart, rend, size, 376 align, boundary, flags, addrp, bshp)) 377 return (ENOMEM); 378 379 return (0); 380 } 381 382 int 383 elroy_memalloc(void *v, bus_addr_t rstart, bus_addr_t rend, bus_size_t size, 384 bus_size_t align, bus_size_t boundary, int flags, bus_addr_t *addrp, 385 bus_space_handle_t *bshp) 386 { 387 struct elroy_softc *sc = v; 388 /* volatile struct elroy_regs *r = sc->sc_regs; */ 389 390 if (bus_space_alloc(sc->sc_bt, rstart, rend, size, 391 align, boundary, flags, addrp, bshp)) 392 return (ENOMEM); 393 394 return (0); 395 } 396 397 void 398 elroy_unmap(void *v, bus_space_handle_t bsh, bus_size_t size) 399 { 400 struct elroy_softc *sc = v; 401 402 bus_space_free(sc->sc_bt, bsh, size); 403 } 404 405 void 406 elroy_free(void *v, bus_space_handle_t bh, bus_size_t size) 407 { 408 /* should be enough */ 409 elroy_unmap(v, bh, size); 410 } 411 412 void 413 elroy_barrier(void *v, bus_space_handle_t h, bus_size_t o, bus_size_t l, int op) 414 { 415 struct elroy_softc *sc = v; 416 volatile struct elroy_regs *r = sc->sc_regs; 417 418 sync_caches(); 419 if (op & BUS_SPACE_BARRIER_WRITE) { 420 (void)r->pci_id; /* flush write fifo */ 421 sync_caches(); 422 } 423 } 424 425 #if NCARDBUS > 0 426 void * 427 elroy_alloc_parent(device_t self, struct pci_attach_args *pa, int io) 428 { 429 #if 0 /* TODO */ 430 431 struct elroy_softc *sc = pa->pa_pc->_cookie; 432 struct extent *ex; 433 bus_space_tag_t tag; 434 bus_addr_t start; 435 bus_size_t size; 436 437 if (io) { 438 ex = sc->sc_ioex; 439 tag = pa->pa_iot; 440 start = 0xa000; 441 size = 0x1000; 442 } else { 443 if (!sc->sc_memex) { 444 bus_space_handle_t memh; 445 bus_addr_t mem_start; 446 447 if (elroy_memalloc(sc, 0xf0800000, 0xff7fffff, 448 ELROY_MEM_WINDOW, ELROY_MEM_WINDOW, EX_NOBOUNDARY, 449 0, &mem_start, &memh)) 450 return (NULL); 451 452 snprintf(sc->sc_memexname, sizeof(sc->sc_memexname), 453 "%s_mem", device_xname(sc->sc_dv)); 454 if ((sc->sc_memex = extent_create(sc->sc_memexname, 455 mem_start, mem_start + ELROY_MEM_WINDOW, 456 NULL, 0, EX_NOWAIT | EX_MALLOCOK)) == NULL) { 457 extent_destroy(sc->sc_ioex); 458 bus_space_free(sc->sc_bt, memh, 459 ELROY_MEM_WINDOW); 460 return (NULL); 461 } 462 } 463 ex = sc->sc_memex; 464 tag = pa->pa_memt; 465 start = ex->ex_start; 466 size = ELROY_MEM_CHUNK; 467 } 468 469 if (extent_alloc_subregion(ex, start, ex->ex_end, size, size, 0, 470 EX_NOBOUNDARY, EX_NOWAIT, &start)) 471 return (NULL); 472 473 extent_free(ex, start, size, EX_NOWAIT); 474 return rbus_new_root_share(tag, ex, start, size, 0); 475 #else 476 return (NULL); 477 #endif 478 } 479 #endif 480 481 void * 482 elroy_vaddr(void *v, bus_space_handle_t h) 483 { 484 return ((void *)h); 485 } 486 487 paddr_t 488 elroy_mmap(void *v, bus_addr_t addr, off_t off, int prot, int flags) 489 { 490 491 return -1; 492 } 493 494 uint8_t 495 elroy_r1(void *v, bus_space_handle_t h, bus_size_t o) 496 { 497 h += o; 498 return *(volatile uint8_t *)h; 499 } 500 501 uint16_t 502 elroy_r2(void *v, bus_space_handle_t h, bus_size_t o) 503 { 504 volatile uint16_t *p; 505 506 h += o; 507 p = (volatile uint16_t *)h; 508 return (le16toh(*p)); 509 } 510 511 uint32_t 512 elroy_r4(void *v, bus_space_handle_t h, bus_size_t o) 513 { 514 uint32_t data; 515 516 h += o; 517 data = *(volatile uint32_t *)h; 518 return (le32toh(data)); 519 } 520 521 uint64_t 522 elroy_r8(void *v, bus_space_handle_t h, bus_size_t o) 523 { 524 uint64_t data; 525 526 h += o; 527 data = *(volatile uint64_t *)h; 528 return (le64toh(data)); 529 } 530 531 void 532 elroy_w1(void *v, bus_space_handle_t h, bus_size_t o, uint8_t vv) 533 { 534 h += o; 535 *(volatile uint8_t *)h = vv; 536 } 537 538 void 539 elroy_w2(void *v, bus_space_handle_t h, bus_size_t o, uint16_t vv) 540 { 541 volatile uint16_t *p; 542 543 h += o; 544 p = (volatile uint16_t *)h; 545 *p = htole16(vv); 546 } 547 548 void 549 elroy_w4(void *v, bus_space_handle_t h, bus_size_t o, uint32_t vv) 550 { 551 h += o; 552 vv = htole32(vv); 553 *(volatile uint32_t *)h = vv; 554 } 555 556 void 557 elroy_w8(void *v, bus_space_handle_t h, bus_size_t o, uint64_t vv) 558 { 559 h += o; 560 *(volatile uint64_t *)h = htole64(vv); 561 } 562 563 564 void 565 elroy_rm_1(void *v, bus_space_handle_t h, bus_size_t o, uint8_t *a, bus_size_t c) 566 { 567 volatile uint8_t *p; 568 569 h += o; 570 p = (volatile uint8_t *)h; 571 while (c--) 572 *a++ = *p; 573 } 574 575 void 576 elroy_rm_2(void *v, bus_space_handle_t h, bus_size_t o, uint16_t *a, bus_size_t c) 577 { 578 volatile uint16_t *p; 579 580 h += o; 581 p = (volatile uint16_t *)h; 582 while (c--) 583 *a++ = le16toh(*p); 584 } 585 586 void 587 elroy_rm_4(void *v, bus_space_handle_t h, bus_size_t o, uint32_t *a, bus_size_t c) 588 { 589 volatile uint32_t *p; 590 591 h += o; 592 p = (volatile uint32_t *)h; 593 while (c--) 594 *a++ = le32toh(*p); 595 } 596 597 void 598 elroy_rm_8(void *v, bus_space_handle_t h, bus_size_t o, uint64_t *a, bus_size_t c) 599 { 600 volatile uint64_t *p; 601 602 h += o; 603 p = (volatile uint64_t *)h; 604 while (c--) 605 *a++ = le64toh(*p); 606 } 607 608 void 609 elroy_wm_1(void *v, bus_space_handle_t h, bus_size_t o, const uint8_t *a, bus_size_t c) 610 { 611 volatile uint8_t *p; 612 613 h += o; 614 p = (volatile uint8_t *)h; 615 while (c--) 616 *p = *a++; 617 } 618 619 void 620 elroy_wm_2(void *v, bus_space_handle_t h, bus_size_t o, const uint16_t *a, bus_size_t c) 621 { 622 volatile uint16_t *p; 623 624 h += o; 625 p = (volatile uint16_t *)h; 626 while (c--) 627 *p = htole16(*a++); 628 } 629 630 void 631 elroy_wm_4(void *v, bus_space_handle_t h, bus_size_t o, const uint32_t *a, bus_size_t c) 632 { 633 volatile uint32_t *p; 634 635 h += o; 636 p = (volatile uint32_t *)h; 637 while (c--) 638 *p = htole32(*a++); 639 } 640 641 void 642 elroy_wm_8(void *v, bus_space_handle_t h, bus_size_t o, const uint64_t *a, bus_size_t c) 643 { 644 volatile uint64_t *p; 645 646 h += o; 647 p = (volatile uint64_t *)h; 648 while (c--) 649 *p = htole64(*a++); 650 } 651 652 void 653 elroy_sm_1(void *v, bus_space_handle_t h, bus_size_t o, uint8_t vv, bus_size_t c) 654 { 655 volatile uint8_t *p; 656 657 h += o; 658 p = (volatile uint8_t *)h; 659 while (c--) 660 *p = vv; 661 } 662 663 void 664 elroy_sm_2(void *v, bus_space_handle_t h, bus_size_t o, uint16_t vv, bus_size_t c) 665 { 666 volatile uint16_t *p; 667 668 h += o; 669 p = (volatile uint16_t *)h; 670 vv = htole16(vv); 671 while (c--) 672 *p = vv; 673 } 674 675 void 676 elroy_sm_4(void *v, bus_space_handle_t h, bus_size_t o, uint32_t vv, bus_size_t c) 677 { 678 volatile uint32_t *p; 679 680 h += o; 681 p = (volatile uint32_t *)h; 682 vv = htole32(vv); 683 while (c--) 684 *p = vv; 685 } 686 687 void 688 elroy_sm_8(void *v, bus_space_handle_t h, bus_size_t o, uint64_t vv, bus_size_t c) 689 { 690 volatile uint64_t *p; 691 692 h += o; 693 p = (volatile uint64_t *)h; 694 vv = htole64(vv); 695 while (c--) 696 *p = vv; 697 } 698 699 void 700 elroy_rrm_2(void *v, bus_space_handle_t h, bus_size_t o, 701 uint16_t *a, bus_size_t c) 702 { 703 volatile uint16_t *p, *q = a; 704 705 h += o; 706 p = (volatile uint16_t *)h; 707 while (c--) 708 *q++ = *p; 709 } 710 711 void 712 elroy_rrm_4(void *v, bus_space_handle_t h, bus_size_t o, 713 uint32_t *a, bus_size_t c) 714 { 715 volatile uint32_t *p, *q = a; 716 717 h += o; 718 p = (volatile uint32_t *)h; 719 while (c--) 720 *q++ = *p; 721 } 722 723 void 724 elroy_rrm_8(void *v, bus_space_handle_t h, bus_size_t o, 725 uint64_t *a, bus_size_t c) 726 { 727 volatile uint64_t *p, *q = a; 728 729 h += o; 730 p = (volatile uint64_t *)h; 731 while (c--) 732 *q++ = *p; 733 } 734 735 void 736 elroy_wrm_2(void *v, bus_space_handle_t h, bus_size_t o, 737 const uint16_t *a, bus_size_t c) 738 { 739 volatile uint16_t *p; 740 const uint16_t *q = a; 741 742 h += o; 743 p = (volatile uint16_t *)h; 744 while (c--) 745 *p = *q++; 746 } 747 748 void 749 elroy_wrm_4(void *v, bus_space_handle_t h, bus_size_t o, 750 const uint32_t *a, bus_size_t c) 751 { 752 volatile uint32_t *p; 753 const uint32_t *q = a; 754 755 h += o; 756 p = (volatile uint32_t *)h; 757 while (c--) 758 *p = *q++; 759 } 760 761 void 762 elroy_wrm_8(void *v, bus_space_handle_t h, bus_size_t o, 763 const uint64_t *a, bus_size_t c) 764 { 765 volatile uint64_t *p; 766 const uint64_t *q = a; 767 768 h += o; 769 p = (volatile uint64_t *)h; 770 while (c--) 771 *p = *q++; 772 } 773 774 void 775 elroy_rr_1(void *v, bus_space_handle_t h, bus_size_t o, uint8_t *a, bus_size_t c) 776 { 777 volatile uint8_t *p; 778 779 h += o; 780 p = (volatile uint8_t *)h; 781 while (c--) 782 *a++ = *p++; 783 } 784 785 void 786 elroy_rr_2(void *v, bus_space_handle_t h, bus_size_t o, uint16_t *a, bus_size_t c) 787 { 788 volatile uint16_t *p, data; 789 790 h += o; 791 p = (volatile uint16_t *)h; 792 while (c--) { 793 data = *p++; 794 *a++ = le16toh(data); 795 } 796 } 797 798 void 799 elroy_rr_4(void *v, bus_space_handle_t h, bus_size_t o, uint32_t *a, bus_size_t c) 800 { 801 volatile uint32_t *p, data; 802 803 h += o; 804 p = (volatile uint32_t *)h; 805 while (c--) { 806 data = *p++; 807 *a++ = le32toh(data); 808 } 809 } 810 811 void 812 elroy_rr_8(void *v, bus_space_handle_t h, bus_size_t o, uint64_t *a, bus_size_t c) 813 { 814 volatile uint64_t *p, data; 815 816 h += o; 817 p = (volatile uint64_t *)h; 818 while (c--) { 819 data = *p++; 820 *a++ = le64toh(data); 821 } 822 } 823 824 void 825 elroy_wr_1(void *v, bus_space_handle_t h, bus_size_t o, const uint8_t *a, bus_size_t c) 826 { 827 volatile uint8_t *p; 828 829 h += o; 830 p = (volatile uint8_t *)h; 831 while (c--) 832 *p++ = *a++; 833 } 834 835 void 836 elroy_wr_2(void *v, bus_space_handle_t h, bus_size_t o, const uint16_t *a, bus_size_t c) 837 { 838 volatile uint16_t *p, data; 839 840 h += o; 841 p = (volatile uint16_t *)h; 842 while (c--) { 843 data = *a++; 844 *p++ = htole16(data); 845 } 846 } 847 848 void 849 elroy_wr_4(void *v, bus_space_handle_t h, bus_size_t o, const uint32_t *a, bus_size_t c) 850 { 851 volatile uint32_t *p, data; 852 853 h += o; 854 p = (volatile uint32_t *)h; 855 while (c--) { 856 data = *a++; 857 *p++ = htole32(data); 858 } 859 } 860 861 void 862 elroy_wr_8(void *v, bus_space_handle_t h, bus_size_t o, const uint64_t *a, bus_size_t c) 863 { 864 volatile uint64_t *p, data; 865 866 h += o; 867 p = (volatile uint64_t *)h; 868 while (c--) { 869 data = *a++; 870 *p++ = htole64(data); 871 } 872 } 873 874 void 875 elroy_rrr_2(void *v, bus_space_handle_t h, bus_size_t o, 876 uint16_t *a, bus_size_t c) 877 { 878 volatile uint16_t *p, *q = a; 879 880 h += o; 881 p = (volatile uint16_t *)h; 882 while (c--) 883 *q++ = *p++; 884 } 885 886 void 887 elroy_rrr_4(void *v, bus_space_handle_t h, bus_size_t o, 888 uint32_t *a, bus_size_t c) 889 { 890 volatile uint32_t *p, *q = a; 891 892 h += o; 893 p = (volatile uint32_t *)h; 894 while (c--) 895 *q++ = *p++; 896 } 897 898 void 899 elroy_rrr_8(void *v, bus_space_handle_t h, bus_size_t o, 900 uint64_t *a, bus_size_t c) 901 { 902 volatile uint64_t *p, *q = a; 903 904 h += o; 905 p = (volatile uint64_t *)h; 906 while (c--) 907 *q++ = *p++; 908 } 909 910 void 911 elroy_wrr_2(void *v, bus_space_handle_t h, bus_size_t o, 912 const uint16_t *a, bus_size_t c) 913 { 914 volatile uint16_t *p; 915 const uint16_t *q = a; 916 917 h += o; 918 p = (volatile uint16_t *)h; 919 while (c--) 920 *p++ = *q++; 921 } 922 923 void 924 elroy_wrr_4(void *v, bus_space_handle_t h, bus_size_t o, 925 const uint32_t *a, bus_size_t c) 926 { 927 volatile uint32_t *p; 928 const uint32_t *q = a; 929 930 h += o; 931 p = (volatile uint32_t *)h; 932 while (c--) 933 *p++ = *q++; 934 } 935 936 void 937 elroy_wrr_8(void *v, bus_space_handle_t h, bus_size_t o, 938 const uint64_t *a, bus_size_t c) 939 { 940 volatile uint64_t *p; 941 const uint64_t *q = a; 942 943 h += o; 944 p = (volatile uint64_t *)h; 945 while (c--) 946 *p++ = *q++; 947 } 948 949 void 950 elroy_sr_1(void *v, bus_space_handle_t h, bus_size_t o, uint8_t vv, bus_size_t c) 951 { 952 volatile uint8_t *p; 953 954 h += o; 955 p = (volatile uint8_t *)h; 956 while (c--) 957 *p++ = vv; 958 } 959 960 void 961 elroy_sr_2(void *v, bus_space_handle_t h, bus_size_t o, uint16_t vv, bus_size_t c) 962 { 963 volatile uint16_t *p; 964 965 h += o; 966 vv = htole16(vv); 967 p = (volatile uint16_t *)h; 968 while (c--) 969 *p++ = vv; 970 } 971 972 void 973 elroy_sr_4(void *v, bus_space_handle_t h, bus_size_t o, uint32_t vv, bus_size_t c) 974 { 975 volatile uint32_t *p; 976 977 h += o; 978 vv = htole32(vv); 979 p = (volatile uint32_t *)h; 980 while (c--) 981 *p++ = vv; 982 } 983 984 void 985 elroy_sr_8(void *v, bus_space_handle_t h, bus_size_t o, uint64_t vv, bus_size_t c) 986 { 987 volatile uint64_t *p; 988 989 h += o; 990 vv = htole64(vv); 991 p = (volatile uint64_t *)h; 992 while (c--) 993 *p++ = vv; 994 } 995 996 void 997 elroy_cp_1(void *v, bus_space_handle_t h1, bus_size_t o1, 998 bus_space_handle_t h2, bus_size_t o2, bus_size_t c) 999 { 1000 while (c--) 1001 elroy_w1(v, h1, o1++, elroy_r1(v, h2, o2++)); 1002 } 1003 1004 void 1005 elroy_cp_2(void *v, bus_space_handle_t h1, bus_size_t o1, 1006 bus_space_handle_t h2, bus_size_t o2, bus_size_t c) 1007 { 1008 while (c--) { 1009 elroy_w2(v, h1, o1, elroy_r2(v, h2, o2)); 1010 o1 += 2; 1011 o2 += 2; 1012 } 1013 } 1014 1015 void 1016 elroy_cp_4(void *v, bus_space_handle_t h1, bus_size_t o1, 1017 bus_space_handle_t h2, bus_size_t o2, bus_size_t c) 1018 { 1019 while (c--) { 1020 elroy_w4(v, h1, o1, elroy_r4(v, h2, o2)); 1021 o1 += 4; 1022 o2 += 4; 1023 } 1024 } 1025 1026 void 1027 elroy_cp_8(void *v, bus_space_handle_t h1, bus_size_t o1, 1028 bus_space_handle_t h2, bus_size_t o2, bus_size_t c) 1029 { 1030 while (c--) { 1031 elroy_w8(v, h1, o1, elroy_r8(v, h2, o2)); 1032 o1 += 8; 1033 o2 += 8; 1034 } 1035 } 1036 1037 const struct hppa_bus_space_tag elroy_iomemt = { 1038 NULL, 1039 1040 NULL, elroy_unmap, elroy_subregion, NULL, elroy_free, 1041 elroy_barrier, elroy_vaddr, elroy_mmap, 1042 elroy_r1, elroy_r2, elroy_r4, elroy_r8, 1043 elroy_w1, elroy_w2, elroy_w4, elroy_w8, 1044 elroy_rm_1, elroy_rm_2, elroy_rm_4, elroy_rm_8, 1045 elroy_wm_1, elroy_wm_2, elroy_wm_4, elroy_wm_8, 1046 elroy_sm_1, elroy_sm_2, elroy_sm_4, elroy_sm_8, 1047 elroy_rrm_2, elroy_rrm_4, elroy_rrm_8, 1048 elroy_wrm_2, elroy_wrm_4, elroy_wrm_8, 1049 elroy_rr_1, elroy_rr_2, elroy_rr_4, elroy_rr_8, 1050 elroy_wr_1, elroy_wr_2, elroy_wr_4, elroy_wr_8, 1051 elroy_rrr_2, elroy_rrr_4, elroy_rrr_8, 1052 elroy_wrr_2, elroy_wrr_4, elroy_wrr_8, 1053 elroy_sr_1, elroy_sr_2, elroy_sr_4, elroy_sr_8, 1054 elroy_cp_1, elroy_cp_2, elroy_cp_4, elroy_cp_8 1055 }; 1056 1057 int 1058 elroy_dmamap_create(void *v, bus_size_t size, int nsegments, 1059 bus_size_t maxsegsz, bus_size_t boundary, int flags, bus_dmamap_t *dmamp) 1060 { 1061 struct elroy_softc *sc = v; 1062 1063 /* TODO check the addresses, boundary, enable dma */ 1064 1065 return (bus_dmamap_create(sc->sc_dmat, size, nsegments, 1066 maxsegsz, boundary, flags, dmamp)); 1067 } 1068 1069 void 1070 elroy_dmamap_destroy(void *v, bus_dmamap_t map) 1071 { 1072 struct elroy_softc *sc = v; 1073 1074 bus_dmamap_destroy(sc->sc_dmat, map); 1075 } 1076 1077 int 1078 elroy_dmamap_load(void *v, bus_dmamap_t map, void *addr, bus_size_t size, 1079 struct proc *p, int flags) 1080 { 1081 struct elroy_softc *sc = v; 1082 1083 return (bus_dmamap_load(sc->sc_dmat, map, addr, size, p, flags)); 1084 } 1085 1086 int 1087 elroy_dmamap_load_mbuf(void *v, bus_dmamap_t map, struct mbuf *m, int flags) 1088 { 1089 struct elroy_softc *sc = v; 1090 1091 return (bus_dmamap_load_mbuf(sc->sc_dmat, map, m, flags)); 1092 } 1093 1094 int 1095 elroy_dmamap_load_uio(void *v, bus_dmamap_t map, struct uio *uio, int flags) 1096 { 1097 struct elroy_softc *sc = v; 1098 1099 return (bus_dmamap_load_uio(sc->sc_dmat, map, uio, flags)); 1100 } 1101 1102 int 1103 elroy_dmamap_load_raw(void *v, bus_dmamap_t map, bus_dma_segment_t *segs, 1104 int nsegs, bus_size_t size, int flags) 1105 { 1106 struct elroy_softc *sc = v; 1107 1108 return (bus_dmamap_load_raw(sc->sc_dmat, map, segs, nsegs, size, flags)); 1109 } 1110 1111 void 1112 elroy_dmamap_unload(void *v, bus_dmamap_t map) 1113 { 1114 struct elroy_softc *sc = v; 1115 1116 bus_dmamap_unload(sc->sc_dmat, map); 1117 } 1118 1119 void 1120 elroy_dmamap_sync(void *v, bus_dmamap_t map, bus_addr_t off, 1121 bus_size_t len, int ops) 1122 { 1123 struct elroy_softc *sc = v; 1124 1125 bus_dmamap_sync(sc->sc_dmat, map, off, len, ops); 1126 } 1127 1128 int 1129 elroy_dmamem_alloc(void *v, bus_size_t size, bus_size_t alignment, 1130 bus_size_t boundary, bus_dma_segment_t *segs, 1131 int nsegs, int *rsegs, int flags) 1132 { 1133 struct elroy_softc *sc = v; 1134 1135 return (bus_dmamem_alloc(sc->sc_dmat, size, alignment, boundary, 1136 segs, nsegs, rsegs, flags)); 1137 } 1138 1139 void 1140 elroy_dmamem_free(void *v, bus_dma_segment_t *segs, int nsegs) 1141 { 1142 struct elroy_softc *sc = v; 1143 1144 bus_dmamem_free(sc->sc_dmat, segs, nsegs); 1145 } 1146 1147 int 1148 elroy_dmamem_map(void *v, bus_dma_segment_t *segs, int nsegs, size_t size, 1149 void **kvap, int flags) 1150 { 1151 struct elroy_softc *sc = v; 1152 1153 return (bus_dmamem_map(sc->sc_dmat, segs, nsegs, size, kvap, flags)); 1154 } 1155 1156 void 1157 elroy_dmamem_unmap(void *v, void *kva, size_t size) 1158 { 1159 struct elroy_softc *sc = v; 1160 1161 bus_dmamem_unmap(sc->sc_dmat, kva, size); 1162 } 1163 1164 paddr_t 1165 elroy_dmamem_mmap(void *v, bus_dma_segment_t *segs, int nsegs, off_t off, 1166 int prot, int flags) 1167 { 1168 struct elroy_softc *sc = v; 1169 1170 return (bus_dmamem_mmap(sc->sc_dmat, segs, nsegs, off, prot, flags)); 1171 } 1172 1173 const struct hppa_bus_dma_tag elroy_dmat = { 1174 NULL, 1175 elroy_dmamap_create, elroy_dmamap_destroy, 1176 elroy_dmamap_load, elroy_dmamap_load_mbuf, 1177 elroy_dmamap_load_uio, elroy_dmamap_load_raw, 1178 elroy_dmamap_unload, elroy_dmamap_sync, 1179 1180 elroy_dmamem_alloc, elroy_dmamem_free, elroy_dmamem_map, 1181 elroy_dmamem_unmap, elroy_dmamem_mmap 1182 }; 1183 1184 const struct hppa_pci_chipset_tag elroy_pc = { 1185 NULL, 1186 elroy_attach_hook, elroy_maxdevs, elroy_make_tag, elroy_decompose_tag, 1187 elroy_conf_read, elroy_conf_write, 1188 apic_intr_map, apic_intr_string, 1189 apic_intr_establish, apic_intr_disestablish, 1190 #if NCARDBUS > 0 1191 elroy_alloc_parent 1192 #else 1193 NULL 1194 #endif 1195 }; 1196 1197 void 1198 elroy_attach(device_t parent, device_t self, void *aux) 1199 { 1200 struct elroy_softc *sc = device_private(self); 1201 struct confargs *ca = (struct confargs *)aux; 1202 struct pcibus_attach_args pba; 1203 volatile struct elroy_regs *r; 1204 const char *p = NULL, *q; 1205 int i; 1206 1207 sc->sc_dv = self; 1208 sc->sc_hpa = ca->ca_hpa; 1209 sc->sc_bt = ca->ca_iot; 1210 sc->sc_dmat = ca->ca_dmatag; 1211 if (bus_space_map(sc->sc_bt, ca->ca_hpa, ca->ca_hpasz, 0, &sc->sc_bh)) { 1212 aprint_error(": can't map space\n"); 1213 return; 1214 } 1215 1216 sc->sc_regs = r = bus_space_vaddr(sc->sc_bt, sc->sc_bh); 1217 elroy_write32(&r->pci_cmdstat, htole32(PCI_COMMAND_IO_ENABLE | 1218 PCI_COMMAND_MEM_ENABLE | PCI_COMMAND_MASTER_ENABLE)); 1219 1220 elroy_write32(&r->control, elroy_read32(&r->control) & 1221 ~htole32(ELROY_CONTROL_RF)); 1222 for (i = 5000; i-- && 1223 elroy_read32(&r->status) & htole32(ELROY_STATUS_RC); DELAY(10)); 1224 if (i < 0) { 1225 char buf[128]; /* XXXNH */ 1226 1227 snprintb(buf, sizeof(buf), ELROY_STATUS_BITS, 1228 htole32(r->status)); 1229 aprint_error(": reset failed; status %s\n", buf); 1230 return; 1231 } 1232 1233 q = ""; 1234 sc->sc_ver = PCI_REVISION(le32toh(elroy_read32(&r->pci_class))); 1235 switch ((ca->ca_type.iodc_model << 4) | 1236 (ca->ca_type.iodc_revision >> 4)) { 1237 case 0x782: 1238 p = "Elroy"; 1239 switch (sc->sc_ver) { 1240 default: 1241 q = "+"; 1242 case 5: sc->sc_ver = 0x40; break; 1243 case 4: sc->sc_ver = 0x30; break; 1244 case 3: sc->sc_ver = 0x22; break; 1245 case 2: sc->sc_ver = 0x21; break; 1246 case 1: sc->sc_ver = 0x20; break; 1247 case 0: sc->sc_ver = 0x10; break; 1248 } 1249 break; 1250 1251 case 0x783: 1252 p = "Mercury"; 1253 break; 1254 1255 case 0x784: 1256 p = "Quicksilver"; 1257 break; 1258 1259 default: 1260 p = "Mojo"; 1261 break; 1262 } 1263 1264 aprint_normal(": %s TR%d.%d%s", p, sc->sc_ver >> 4, sc->sc_ver & 0xf, 1265 q); 1266 apic_attach(sc); 1267 aprint_normal("\n"); 1268 1269 elroy_write32(&r->imask, htole32(0xffffffff << 30)); 1270 elroy_write32(&r->ibase, htole32(ELROY_BASE_RE)); 1271 1272 /* TODO reserve elroy's pci space ? */ 1273 1274 #if 0 1275 printf("lmm %llx/%llx gmm %llx/%llx wlm %llx/%llx wgm %llx/%llx io %llx/%llx eio %llx/%llx\n", 1276 le64toh(r->lmmio_base), le64toh(r->lmmio_mask), 1277 le64toh(r->gmmio_base), le64toh(r->gmmio_mask), 1278 le64toh(r->wlmmio_base), le64toh(r->wlmmio_mask), 1279 le64toh(r->wgmmio_base), le64toh(r->wgmmio_mask), 1280 le64toh(r->io_base), le64toh(r->io_mask), 1281 le64toh(r->eio_base), le64toh(r->eio_mask)); 1282 #endif 1283 1284 /* XXX evil hack! */ 1285 sc->sc_iobase = 0xfee00000; 1286 1287 sc->sc_iot = elroy_iomemt; 1288 sc->sc_iot.hbt_cookie = sc; 1289 sc->sc_iot.hbt_map = elroy_iomap; 1290 sc->sc_iot.hbt_alloc = elroy_ioalloc; 1291 sc->sc_memt = elroy_iomemt; 1292 sc->sc_memt.hbt_cookie = sc; 1293 sc->sc_memt.hbt_map = elroy_memmap; 1294 sc->sc_memt.hbt_alloc = elroy_memalloc; 1295 sc->sc_pc = elroy_pc; 1296 sc->sc_pc._cookie = sc; 1297 sc->sc_dmatag = elroy_dmat; 1298 sc->sc_dmatag._cookie = sc; 1299 1300 memset(&pba, 0, sizeof(pba)); 1301 pba.pba_iot = &sc->sc_iot; 1302 pba.pba_memt = &sc->sc_memt; 1303 pba.pba_dmat = &sc->sc_dmatag; 1304 pba.pba_pc = &sc->sc_pc; 1305 pba.pba_bus = 0; /* (le32toh(elroy_read32(&r->busnum)) & 0xff) >> 4; */ 1306 pba.pba_flags = PCI_FLAGS_IO_OKAY | PCI_FLAGS_MEM_OKAY; 1307 1308 config_found_ia(self, "pcibus", &pba, pcibusprint); 1309 } 1310