1 /* $NetBSD: shpcic.c,v 1.9 2005/12/11 12:18:58 christos Exp $ */ 2 3 /* 4 * Copyright (c) 2005 NONAKA Kimihiro 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 #include <sys/cdefs.h> 29 __KERNEL_RCSID(0, "$NetBSD: shpcic.c,v 1.9 2005/12/11 12:18:58 christos Exp $"); 30 31 #include "opt_pci.h" 32 33 #include <sys/param.h> 34 #include <sys/systm.h> 35 #include <sys/kernel.h> 36 #include <sys/device.h> 37 #include <sys/extent.h> 38 #include <sys/malloc.h> 39 40 #include <dev/pci/pcireg.h> 41 #include <dev/pci/pcivar.h> 42 #include <dev/pci/pciconf.h> 43 #include <dev/pci/pcidevs.h> 44 45 #include <sh3/bscreg.h> 46 #include <sh3/cache.h> 47 #include <sh3/exception.h> 48 #include <sh3/pcicreg.h> 49 50 #include <machine/bus.h> 51 #include <machine/intr.h> 52 #include <machine/pci_machdep.h> 53 54 #if defined(SHPCIC_DEBUG) 55 int shpcic_debug = 0; 56 #define DPRINTF(arg) if (shpcic_debug) printf arg 57 #else 58 #define DPRINTF(arg) 59 #endif 60 61 #define PCI_MODE1_ENABLE 0x80000000UL 62 63 static const struct shpcic_product { 64 uint32_t sp_product; 65 const char *sp_name; 66 } shpcic_products[] = { 67 { PCI_PRODUCT_HITACHI_SH7751, "SH7751" }, 68 { PCI_PRODUCT_HITACHI_SH7751R, "SH7751R" }, 69 70 { 0, NULL }, 71 }; 72 73 int shpcic_match(struct device *, struct cfdata *, void *); 74 void shpcic_attach(struct device *, struct device *, void *); 75 76 CFATTACH_DECL(shpcic, sizeof(struct device), 77 shpcic_match, shpcic_attach, NULL, NULL); 78 79 /* There can be only one. */ 80 int shpcic_found = 0; 81 82 /* PCIC intr priotiry */ 83 static int shpcic_intr_priority[2] = { IPL_BIO, IPL_BIO }; 84 85 static const struct shpcic_product *shpcic_lookup(void); 86 87 static const struct shpcic_product * 88 shpcic_lookup(void) 89 { 90 const struct shpcic_product *spp; 91 pcireg_t id; 92 93 id = _reg_read_4(SH4_PCICONF0); 94 switch (PCI_VENDOR(id)) { 95 case PCI_VENDOR_HITACHI: 96 break; 97 98 default: 99 return (NULL); 100 } 101 102 for (spp = shpcic_products; spp->sp_name != NULL; spp++) { 103 if (PCI_PRODUCT(id) == spp->sp_product) { 104 return (spp); 105 } 106 } 107 return (NULL); 108 } 109 110 int 111 shpcic_match(struct device *parent, struct cfdata *cf, void *aux) 112 { 113 114 if (!CPU_IS_SH4) 115 return (0); 116 117 switch (cpu_product) { 118 default: 119 return (0); 120 121 case CPU_PRODUCT_7751: 122 case CPU_PRODUCT_7751R: 123 break; 124 } 125 126 if (shpcic_found) 127 return (0); 128 129 if (shpcic_lookup() == NULL) 130 return (0); 131 132 if (_reg_read_2(SH4_BCR2) & BCR2_PORTEN) 133 return (0); 134 135 return (1); 136 } 137 138 void 139 shpcic_attach(struct device *parent, struct device *self, void *aux) 140 { 141 const struct shpcic_product *spp; 142 struct pcibus_attach_args pba; 143 #ifdef PCI_NETBSD_CONFIGURE 144 struct extent *ioext, *memext; 145 #endif 146 147 shpcic_found = 1; 148 149 spp = shpcic_lookup(); 150 if (spp == NULL) { 151 printf("\n"); 152 panic("shpcic_attach: impossible"); 153 } 154 155 if (_reg_read_2(SH4_BCR2) & BCR2_PORTEN) { 156 printf("\n"); 157 panic("shpcic_attach: port enabled"); 158 } 159 160 printf(": HITACHI %s\n", spp->sp_name); 161 162 /* allow PCIC request */ 163 _reg_write_4(SH4_BCR1, _reg_read_4(SH4_BCR1) | BCR1_BREQEN); 164 165 /* Initialize PCIC */ 166 _reg_write_4(SH4_PCICR, PCICR_BASE | PCICR_RSTCTL); 167 delay(10 * 1000); 168 _reg_write_4(SH4_PCICR, PCICR_BASE); 169 170 /* Class: Host-Bridge */ 171 _reg_write_4(SH4_PCICONF2, 172 PCI_CLASS_CODE(PCI_CLASS_BRIDGE, PCI_SUBCLASS_BRIDGE_HOST, 0x00)); 173 174 #if !defined(DONT_INIT_PCIBSC) 175 #if defined(PCIBCR_BCR1_VAL) 176 _reg_write_4(SH4_PCIBCR1, PCIBCR_BCR1_VAL); 177 #else 178 _reg_write_4(SH4_PCIBCR1, _reg_read_4(SH4_BCR1) | BCR1_MASTER); 179 #endif 180 #if defined(PCIBCR_BCR2_VAL) 181 _reg_write_4(SH4_PCIBCR2, PCIBCR_BCR2_VAL); 182 #else 183 _reg_write_4(SH4_PCIBCR2, _reg_read_2(SH4_BCR2)); 184 #endif 185 #if defined(SH4) && defined(SH7751R) 186 if (cpu_product == CPU_PRODUCT_7751R) { 187 #if defined(PCIBCR_BCR3_VAL) 188 _reg_write_4(SH4_PCIBCR3, PCIBCR_BCR3_VAL); 189 #else 190 _reg_write_4(SH4_PCIBCR3, _reg_read_2(SH4_BCR3)); 191 #endif 192 } 193 #endif /* SH4 && SH7751R && PCIBCR_BCR3_VAL */ 194 #if defined(PCIBCR_WCR1_VAL) 195 _reg_write_4(SH4_PCIWCR1, PCIBCR_WCR1_VAL); 196 #else 197 _reg_write_4(SH4_PCIWCR1, _reg_read_4(SH4_WCR1)); 198 #endif 199 #if defined(PCIBCR_WCR2_VAL) 200 _reg_write_4(SH4_PCIWCR2, PCIBCR_WCR2_VAL); 201 #else 202 _reg_write_4(SH4_PCIWCR2, _reg_read_4(SH4_WCR2)); 203 #endif 204 #if defined(PCIBCR_WCR3_VAL) 205 _reg_write_4(SH4_PCIWCR3, PCIBCR_WCR3_VAL); 206 #else 207 _reg_write_4(SH4_PCIWCR3, _reg_read_4(SH4_WCR3)); 208 #endif 209 #if defined(PCIBCR_MCR_VAL) 210 _reg_write_4(SH4_PCIMCR, PCIBCR_MCR_VAL); 211 #else 212 _reg_write_4(SH4_PCIMCR, _reg_read_4(SH4_MCR)); 213 #endif 214 #endif /* !DONT_INIT_PCIBSC */ 215 216 /* set PCI I/O, memory base address */ 217 _reg_write_4(SH4_PCIIOBR, SH4_PCIC_IO); 218 _reg_write_4(SH4_PCIMBR, SH4_PCIC_MEM); 219 220 /* set PCI local address 0 */ 221 _reg_write_4(SH4_PCILSR0, (64 - 1) << 20); 222 _reg_write_4(SH4_PCILAR0, 0xac000000); 223 _reg_write_4(SH4_PCICONF5, 0xac000000); 224 225 /* set PCI local address 1 */ 226 _reg_write_4(SH4_PCILSR1, (64 - 1) << 20); 227 _reg_write_4(SH4_PCILAR1, 0xac000000); 228 _reg_write_4(SH4_PCICONF6, 0x8c000000); 229 230 /* Enable I/O, memory, bus-master */ 231 _reg_write_4(SH4_PCICONF1, PCI_COMMAND_IO_ENABLE 232 | PCI_COMMAND_MEM_ENABLE 233 | PCI_COMMAND_MASTER_ENABLE 234 | PCI_COMMAND_STEPPING_ENABLE 235 | PCI_STATUS_DEVSEL_MEDIUM); 236 237 /* Initialize done. */ 238 _reg_write_4(SH4_PCICR, PCICR_BASE | PCICR_CFINIT); 239 240 /* set PCI controller interrupt priority */ 241 intpri_intr_priority(SH4_INTEVT_PCIERR, shpcic_intr_priority[0]); 242 intpri_intr_priority(SH4_INTEVT_PCISERR, shpcic_intr_priority[1]); 243 244 /* PCI bus */ 245 #ifdef PCI_NETBSD_CONFIGURE 246 ioext = extent_create("pciio", 247 SH4_PCIC_IO, SH4_PCIC_IO + SH4_PCIC_IO_SIZE - 1, 248 M_DEVBUF, NULL, 0, EX_NOWAIT); 249 memext = extent_create("pcimem", 250 SH4_PCIC_MEM, SH4_PCIC_MEM + SH4_PCIC_MEM_SIZE - 1, 251 M_DEVBUF, NULL, 0, EX_NOWAIT); 252 253 pci_configure_bus(NULL, ioext, memext, NULL, 0, sh_cache_line_size); 254 255 extent_destroy(ioext); 256 extent_destroy(memext); 257 #endif 258 259 /* PCI bus */ 260 memset(&pba, 0, sizeof(pba)); 261 pba.pba_iot = shpcic_get_bus_io_tag(); 262 pba.pba_memt = shpcic_get_bus_mem_tag(); 263 pba.pba_dmat = shpcic_get_bus_dma_tag(); 264 pba.pba_dmat64 = NULL; 265 pba.pba_pc = NULL; 266 pba.pba_bus = 0; 267 pba.pba_bridgetag = NULL; 268 pba.pba_flags = PCI_FLAGS_IO_ENABLED | PCI_FLAGS_MEM_ENABLED; 269 config_found(self, &pba, NULL); 270 } 271 272 int 273 shpcic_bus_maxdevs(void *v, int busno) 274 { 275 276 /* 277 * Bus number is irrelevant. Configuration Mechanism 1 is in 278 * use, can have devices 0-32 (i.e. the `normal' range). 279 */ 280 return (32); 281 } 282 283 pcitag_t 284 shpcic_make_tag(void *v, int bus, int device, int function) 285 { 286 pcitag_t tag; 287 288 if (bus >= 256 || device >= 32 || function >= 8) 289 panic("pci_make_tag: bad request"); 290 291 tag = PCI_MODE1_ENABLE | 292 (bus << 16) | (device << 11) | (function << 8); 293 294 return (tag); 295 } 296 297 void 298 shpcic_decompose_tag(void *v, pcitag_t tag, int *bp, int *dp, int *fp) 299 { 300 301 if (bp != NULL) 302 *bp = (tag >> 16) & 0xff; 303 if (dp != NULL) 304 *dp = (tag >> 11) & 0x1f; 305 if (fp != NULL) 306 *fp = (tag >> 8) & 0x7; 307 } 308 309 pcireg_t 310 shpcic_conf_read(void *v, pcitag_t tag, int reg) 311 { 312 pcireg_t data; 313 int s; 314 315 s = splhigh(); 316 _reg_write_4(SH4_PCIPAR, tag | reg); 317 data = _reg_read_4(SH4_PCIPDR); 318 _reg_write_4(SH4_PCIPAR, 0); 319 splx(s); 320 321 return data; 322 } 323 324 void 325 shpcic_conf_write(void *v, pcitag_t tag, int reg, pcireg_t data) 326 { 327 int s; 328 329 s = splhigh(); 330 _reg_write_4(SH4_PCIPAR, tag | reg); 331 _reg_write_4(SH4_PCIPDR, data); 332 _reg_write_4(SH4_PCIPAR, 0); 333 splx(s); 334 } 335 336 int 337 shpcic_set_intr_priority(int intr, int level) 338 { 339 int evtcode; 340 341 if ((intr != 0) && (intr != 1)) { 342 return (-1); 343 } 344 if ((level < IPL_NONE) || (level > IPL_HIGH)) { 345 return (-1); 346 } 347 348 if (intr == 0) { 349 evtcode = SH4_INTEVT_PCIERR; 350 } else { 351 evtcode = SH4_INTEVT_PCISERR; 352 } 353 354 intpri_intr_priority(evtcode, shpcic_intr_priority[intr]); 355 shpcic_intr_priority[intr] = level; 356 357 return (0); 358 } 359 360 void * 361 shpcic_intr_establish(int evtcode, int (*ih_func)(void *), void *ih_arg) 362 { 363 int level; 364 365 switch (evtcode) { 366 case SH4_INTEVT_PCISERR: 367 level = shpcic_intr_priority[1]; 368 break; 369 370 case SH4_INTEVT_PCIDMA3: 371 case SH4_INTEVT_PCIDMA2: 372 case SH4_INTEVT_PCIDMA1: 373 case SH4_INTEVT_PCIDMA0: 374 case SH4_INTEVT_PCIPWON: 375 case SH4_INTEVT_PCIPWDWN: 376 case SH4_INTEVT_PCIERR: 377 level = shpcic_intr_priority[0]; 378 break; 379 380 default: 381 printf("shpcic_intr_establish: unknown evtcode = 0x%08x\n", 382 evtcode); 383 return NULL; 384 } 385 386 return intc_intr_establish(evtcode, IST_LEVEL, level, ih_func, ih_arg); 387 } 388 389 void 390 shpcic_intr_disestablish(void *ih) 391 { 392 393 intc_intr_disestablish(ih); 394 } 395 396 /* 397 * shpcic bus space 398 */ 399 int 400 shpcic_iomem_map(void *v, bus_addr_t bpa, bus_size_t size, 401 int flags, bus_space_handle_t *bshp) 402 { 403 404 *bshp = (bus_space_handle_t)bpa; 405 406 return (0); 407 } 408 409 void 410 shpcic_iomem_unmap(void *v, bus_space_handle_t bsh, bus_size_t size) 411 { 412 413 /* Nothing to do */ 414 } 415 416 int 417 shpcic_iomem_subregion(void *v, bus_space_handle_t bsh, 418 bus_size_t offset, bus_size_t size, bus_space_handle_t *nbshp) 419 { 420 421 *nbshp = bsh + offset; 422 423 return (0); 424 } 425 426 int 427 shpcic_iomem_alloc(void *v, bus_addr_t rstart, bus_addr_t rend, 428 bus_size_t size, bus_size_t alignment, bus_size_t boundary, int flags, 429 bus_addr_t *bpap, bus_space_handle_t *bshp) 430 { 431 432 *bshp = *bpap = rstart; 433 434 return (0); 435 } 436 437 void 438 shpcic_iomem_free(void *v, bus_space_handle_t bsh, bus_size_t size) 439 { 440 441 /* Nothing to do */ 442 } 443 444 /* 445 * shpcic bus space io/mem read/write 446 */ 447 /* read */ 448 static __inline uint8_t __shpcic_io_read_1(bus_space_handle_t bsh, 449 bus_size_t offset); 450 static __inline uint16_t __shpcic_io_read_2(bus_space_handle_t bsh, 451 bus_size_t offset); 452 static __inline uint32_t __shpcic_io_read_4(bus_space_handle_t bsh, 453 bus_size_t offset); 454 static __inline uint8_t __shpcic_mem_read_1(bus_space_handle_t bsh, 455 bus_size_t offset); 456 static __inline uint16_t __shpcic_mem_read_2(bus_space_handle_t bsh, 457 bus_size_t offset); 458 static __inline uint32_t __shpcic_mem_read_4(bus_space_handle_t bsh, 459 bus_size_t offset); 460 461 static __inline uint8_t 462 __shpcic_io_read_1(bus_space_handle_t bsh, bus_size_t offset) 463 { 464 u_long adr = (u_long)(bsh + offset) & SH4_PCIC_IO_MASK; 465 466 return *(volatile uint8_t *)(SH4_PCIC_IO + adr); 467 } 468 469 static __inline uint16_t 470 __shpcic_io_read_2(bus_space_handle_t bsh, bus_size_t offset) 471 { 472 u_long adr = (u_long)(bsh + offset) & SH4_PCIC_IO_MASK; 473 474 return *(volatile uint16_t *)(SH4_PCIC_IO + adr); 475 } 476 477 static __inline uint32_t 478 __shpcic_io_read_4(bus_space_handle_t bsh, bus_size_t offset) 479 { 480 u_long adr = (u_long)(bsh + offset) & SH4_PCIC_IO_MASK; 481 482 return *(volatile uint32_t *)(SH4_PCIC_IO + adr); 483 } 484 485 static __inline uint8_t 486 __shpcic_mem_read_1(bus_space_handle_t bsh, bus_size_t offset) 487 { 488 u_long adr = (u_long)(bsh + offset) & SH4_PCIC_MEM_MASK; 489 490 return *(volatile uint8_t *)(SH4_PCIC_MEM + adr); 491 } 492 493 static __inline uint16_t 494 __shpcic_mem_read_2(bus_space_handle_t bsh, bus_size_t offset) 495 { 496 u_long adr = (u_long)(bsh + offset) & SH4_PCIC_MEM_MASK; 497 498 return *(volatile uint16_t *)(SH4_PCIC_MEM + adr); 499 } 500 501 static __inline uint32_t 502 __shpcic_mem_read_4(bus_space_handle_t bsh, bus_size_t offset) 503 { 504 u_long adr = (u_long)(bsh + offset) & SH4_PCIC_MEM_MASK; 505 506 return *(volatile uint32_t *)(SH4_PCIC_MEM + adr); 507 } 508 509 /* 510 * read single 511 */ 512 uint8_t 513 shpcic_io_read_1(void *v, bus_space_handle_t bsh, bus_size_t offset) 514 { 515 uint8_t value; 516 517 value = __shpcic_io_read_1(bsh, offset); 518 519 return value; 520 } 521 522 uint16_t 523 shpcic_io_read_2(void *v, bus_space_handle_t bsh, bus_size_t offset) 524 { 525 uint16_t value; 526 527 value = __shpcic_io_read_2(bsh, offset); 528 529 return value; 530 } 531 532 uint32_t 533 shpcic_io_read_4(void *v, bus_space_handle_t bsh, bus_size_t offset) 534 { 535 uint32_t value; 536 537 value = __shpcic_io_read_4(bsh, offset); 538 539 return value; 540 } 541 542 uint8_t 543 shpcic_mem_read_1(void *v, bus_space_handle_t bsh, bus_size_t offset) 544 { 545 uint8_t value; 546 547 value = __shpcic_mem_read_1(bsh, offset); 548 549 return value; 550 } 551 552 uint16_t 553 shpcic_mem_read_2(void *v, bus_space_handle_t bsh, bus_size_t offset) 554 { 555 uint16_t value; 556 557 value = __shpcic_mem_read_2(bsh, offset); 558 559 return value; 560 } 561 562 uint32_t 563 shpcic_mem_read_4(void *v, bus_space_handle_t bsh, bus_size_t offset) 564 { 565 uint32_t value; 566 567 value = __shpcic_mem_read_4(bsh, offset); 568 569 return value; 570 } 571 572 /* 573 * read multi 574 */ 575 void 576 shpcic_io_read_multi_1(void *v, bus_space_handle_t bsh, 577 bus_size_t offset, uint8_t *addr, bus_size_t count) 578 { 579 580 while (count--) { 581 *addr++ = __shpcic_io_read_1(bsh, offset); 582 } 583 } 584 585 void 586 shpcic_io_read_multi_2(void *v, bus_space_handle_t bsh, 587 bus_size_t offset, uint16_t *addr, bus_size_t count) 588 { 589 590 while (count--) { 591 *addr++ = __shpcic_io_read_2(bsh, offset); 592 } 593 } 594 595 void 596 shpcic_io_read_multi_4(void *v, bus_space_handle_t bsh, 597 bus_size_t offset, uint32_t *addr, bus_size_t count) 598 { 599 600 while (count--) { 601 *addr++ = __shpcic_io_read_4(bsh, offset); 602 } 603 } 604 605 void 606 shpcic_mem_read_multi_1(void *v, bus_space_handle_t bsh, 607 bus_size_t offset, uint8_t *addr, bus_size_t count) 608 { 609 610 while (count--) { 611 *addr++ = __shpcic_mem_read_1(bsh, offset); 612 } 613 } 614 615 void 616 shpcic_mem_read_multi_2(void *v, bus_space_handle_t bsh, 617 bus_size_t offset, uint16_t *addr, bus_size_t count) 618 { 619 620 while (count--) { 621 *addr++ = __shpcic_mem_read_2(bsh, offset); 622 } 623 } 624 625 void 626 shpcic_mem_read_multi_4(void *v, bus_space_handle_t bsh, 627 bus_size_t offset, uint32_t *addr, bus_size_t count) 628 { 629 630 while (count--) { 631 *addr++ = __shpcic_mem_read_4(bsh, offset); 632 } 633 } 634 635 /* 636 * 637 * read region 638 */ 639 void 640 shpcic_io_read_region_1(void *v, bus_space_handle_t bsh, 641 bus_size_t offset, uint8_t *addr, bus_size_t count) 642 { 643 644 while (count--) { 645 *addr++ = __shpcic_io_read_1(bsh, offset); 646 offset += 1; 647 } 648 } 649 650 void 651 shpcic_io_read_region_2(void *v, bus_space_handle_t bsh, 652 bus_size_t offset, uint16_t *addr, bus_size_t count) 653 { 654 655 while (count--) { 656 *addr++ = __shpcic_io_read_2(bsh, offset); 657 offset += 2; 658 } 659 } 660 661 void 662 shpcic_io_read_region_4(void *v, bus_space_handle_t bsh, 663 bus_size_t offset, uint32_t *addr, bus_size_t count) 664 { 665 666 while (count--) { 667 *addr++ = __shpcic_io_read_4(bsh, offset); 668 offset += 4; 669 } 670 } 671 672 void 673 shpcic_mem_read_region_1(void *v, bus_space_handle_t bsh, 674 bus_size_t offset, uint8_t *addr, bus_size_t count) 675 { 676 677 while (count--) { 678 *addr++ = __shpcic_mem_read_1(bsh, offset); 679 offset += 1; 680 } 681 } 682 683 void 684 shpcic_mem_read_region_2(void *v, bus_space_handle_t bsh, 685 bus_size_t offset, uint16_t *addr, bus_size_t count) 686 { 687 688 while (count--) { 689 *addr++ = __shpcic_mem_read_2(bsh, offset); 690 offset += 2; 691 } 692 } 693 694 void 695 shpcic_mem_read_region_4(void *v, bus_space_handle_t bsh, 696 bus_size_t offset, uint32_t *addr, bus_size_t count) 697 { 698 699 while (count--) { 700 *addr++ = __shpcic_mem_read_4(bsh, offset); 701 offset += 4; 702 } 703 } 704 705 /* write */ 706 static __inline void __shpcic_io_write_1(bus_space_handle_t bsh, 707 bus_size_t offset, uint8_t value); 708 static __inline void __shpcic_io_write_2(bus_space_handle_t bsh, 709 bus_size_t offset, uint16_t value); 710 static __inline void __shpcic_io_write_4(bus_space_handle_t bsh, 711 bus_size_t offset, uint32_t value); 712 static __inline void __shpcic_mem_write_1(bus_space_handle_t bsh, 713 bus_size_t offset, uint8_t value); 714 static __inline void __shpcic_mem_write_2(bus_space_handle_t bsh, 715 bus_size_t offset, uint16_t value); 716 static __inline void __shpcic_mem_write_4(bus_space_handle_t bsh, 717 bus_size_t offset, uint32_t value); 718 719 static __inline void 720 __shpcic_io_write_1(bus_space_handle_t bsh, bus_size_t offset, 721 uint8_t value) 722 { 723 u_long adr = (u_long)(bsh + offset) & SH4_PCIC_IO_MASK; 724 725 *(volatile uint8_t *)(SH4_PCIC_IO + adr) = value; 726 } 727 728 static __inline void 729 __shpcic_io_write_2(bus_space_handle_t bsh, bus_size_t offset, 730 uint16_t value) 731 { 732 u_long adr = (u_long)(bsh + offset) & SH4_PCIC_IO_MASK; 733 734 *(volatile uint16_t *)(SH4_PCIC_IO + adr) = value; 735 } 736 737 static __inline void 738 __shpcic_io_write_4(bus_space_handle_t bsh, bus_size_t offset, 739 uint32_t value) 740 { 741 u_long adr = (u_long)(bsh + offset) & SH4_PCIC_IO_MASK; 742 743 *(volatile uint32_t *)(SH4_PCIC_IO + adr) = value; 744 } 745 746 static __inline void 747 __shpcic_mem_write_1(bus_space_handle_t bsh, bus_size_t offset, 748 uint8_t value) 749 { 750 u_long adr = (u_long)(bsh + offset) & SH4_PCIC_MEM_MASK; 751 752 *(volatile uint8_t *)(SH4_PCIC_MEM + adr) = value; 753 } 754 755 static __inline void 756 __shpcic_mem_write_2(bus_space_handle_t bsh, bus_size_t offset, 757 uint16_t value) 758 { 759 u_long adr = (u_long)(bsh + offset) & SH4_PCIC_MEM_MASK; 760 761 *(volatile uint16_t *)(SH4_PCIC_MEM + adr) = value; 762 } 763 764 static __inline void 765 __shpcic_mem_write_4(bus_space_handle_t bsh, bus_size_t offset, 766 uint32_t value) 767 { 768 u_long adr = (u_long)(bsh + offset) & SH4_PCIC_MEM_MASK; 769 770 *(volatile uint32_t *)(SH4_PCIC_MEM + adr) = value; 771 } 772 773 /* 774 * write single 775 */ 776 void 777 shpcic_io_write_1(void *v, bus_space_handle_t bsh, 778 bus_size_t offset, uint8_t value) 779 { 780 781 __shpcic_io_write_1(bsh, offset, value); 782 } 783 784 void 785 shpcic_io_write_2(void *v, bus_space_handle_t bsh, 786 bus_size_t offset, uint16_t value) 787 { 788 789 __shpcic_io_write_2(bsh, offset, value); 790 } 791 792 void 793 shpcic_io_write_4(void *v, bus_space_handle_t bsh, 794 bus_size_t offset, uint32_t value) 795 { 796 797 __shpcic_io_write_4(bsh, offset, value); 798 } 799 800 void 801 shpcic_mem_write_1(void *v, bus_space_handle_t bsh, 802 bus_size_t offset, uint8_t value) 803 { 804 805 __shpcic_mem_write_1(bsh, offset, value); 806 } 807 808 void 809 shpcic_mem_write_2(void *v, bus_space_handle_t bsh, 810 bus_size_t offset, uint16_t value) 811 { 812 813 __shpcic_mem_write_2(bsh, offset, value); 814 } 815 816 void 817 shpcic_mem_write_4(void *v, bus_space_handle_t bsh, 818 bus_size_t offset, uint32_t value) 819 { 820 821 __shpcic_mem_write_4(bsh, offset, value); 822 } 823 824 /* 825 * write multi 826 */ 827 void 828 shpcic_io_write_multi_1(void *v, bus_space_handle_t bsh, 829 bus_size_t offset, const uint8_t *addr, bus_size_t count) 830 { 831 832 while (count--) { 833 __shpcic_io_write_1(bsh, offset, *addr++); 834 } 835 } 836 837 void 838 shpcic_io_write_multi_2(void *v, bus_space_handle_t bsh, 839 bus_size_t offset, const uint16_t *addr, bus_size_t count) 840 { 841 842 while (count--) { 843 __shpcic_io_write_2(bsh, offset, *addr++); 844 } 845 } 846 847 void 848 shpcic_io_write_multi_4(void *v, bus_space_handle_t bsh, 849 bus_size_t offset, const uint32_t *addr, bus_size_t count) 850 { 851 852 while (count--) { 853 __shpcic_io_write_4(bsh, offset, *addr++); 854 } 855 } 856 857 void 858 shpcic_mem_write_multi_1(void *v, bus_space_handle_t bsh, 859 bus_size_t offset, const uint8_t *addr, bus_size_t count) 860 { 861 862 while (count--) { 863 __shpcic_mem_write_1(bsh, offset, *addr++); 864 } 865 } 866 867 void 868 shpcic_mem_write_multi_2(void *v, bus_space_handle_t bsh, 869 bus_size_t offset, const uint16_t *addr, bus_size_t count) 870 { 871 872 while (count--) { 873 __shpcic_mem_write_2(bsh, offset, *addr++); 874 } 875 } 876 877 void 878 shpcic_mem_write_multi_4(void *v, bus_space_handle_t bsh, 879 bus_size_t offset, const uint32_t *addr, bus_size_t count) 880 { 881 882 while (count--) { 883 __shpcic_mem_write_4(bsh, offset, *addr++); 884 } 885 } 886 887 /* 888 * write region 889 */ 890 void 891 shpcic_io_write_region_1(void *v, bus_space_handle_t bsh, 892 bus_size_t offset, const uint8_t *addr, bus_size_t count) 893 { 894 895 while (count--) { 896 __shpcic_io_write_1(bsh, offset, *addr++); 897 offset += 1; 898 } 899 } 900 901 void 902 shpcic_io_write_region_2(void *v, bus_space_handle_t bsh, 903 bus_size_t offset, const uint16_t *addr, bus_size_t count) 904 { 905 906 while (count--) { 907 __shpcic_io_write_2(bsh, offset, *addr++); 908 offset += 2; 909 } 910 } 911 912 void 913 shpcic_io_write_region_4(void *v, bus_space_handle_t bsh, 914 bus_size_t offset, const uint32_t *addr, bus_size_t count) 915 { 916 917 while (count--) { 918 __shpcic_io_write_4(bsh, offset, *addr++); 919 offset += 4; 920 } 921 } 922 923 void 924 shpcic_mem_write_region_1(void *v, bus_space_handle_t bsh, 925 bus_size_t offset, const uint8_t *addr, bus_size_t count) 926 { 927 928 while (count--) { 929 __shpcic_mem_write_1(bsh, offset, *addr++); 930 offset += 1; 931 } 932 } 933 934 void 935 shpcic_mem_write_region_2(void *v, bus_space_handle_t bsh, 936 bus_size_t offset, const uint16_t *addr, bus_size_t count) 937 { 938 939 while (count--) { 940 __shpcic_mem_write_2(bsh, offset, *addr++); 941 offset += 2; 942 } 943 } 944 945 void 946 shpcic_mem_write_region_4(void *v, bus_space_handle_t bsh, 947 bus_size_t offset, const uint32_t *addr, bus_size_t count) 948 { 949 950 while (count--) { 951 __shpcic_mem_write_4(bsh, offset, *addr++); 952 offset += 4; 953 } 954 } 955 956 /* 957 * set multi 958 */ 959 void 960 shpcic_io_set_multi_1(void *v, bus_space_handle_t bsh, 961 bus_size_t offset, uint8_t value, bus_size_t count) 962 { 963 964 while (count--) { 965 __shpcic_io_write_1(bsh, offset, value); 966 } 967 } 968 969 void 970 shpcic_io_set_multi_2(void *v, bus_space_handle_t bsh, 971 bus_size_t offset, uint16_t value, bus_size_t count) 972 { 973 974 while (count--) { 975 __shpcic_io_write_2(bsh, offset, value); 976 } 977 } 978 979 void 980 shpcic_io_set_multi_4(void *v, bus_space_handle_t bsh, 981 bus_size_t offset, uint32_t value, bus_size_t count) 982 { 983 984 while (count--) { 985 __shpcic_io_write_4(bsh, offset, value); 986 } 987 } 988 989 void 990 shpcic_mem_set_multi_1(void *v, bus_space_handle_t bsh, 991 bus_size_t offset, uint8_t value, bus_size_t count) 992 { 993 994 while (count--) { 995 __shpcic_mem_write_1(bsh, offset, value); 996 } 997 } 998 999 void 1000 shpcic_mem_set_multi_2(void *v, bus_space_handle_t bsh, 1001 bus_size_t offset, uint16_t value, bus_size_t count) 1002 { 1003 1004 while (count--) { 1005 __shpcic_mem_write_2(bsh, offset, value); 1006 } 1007 } 1008 1009 void 1010 shpcic_mem_set_multi_4(void *v, bus_space_handle_t bsh, 1011 bus_size_t offset, uint32_t value, bus_size_t count) 1012 { 1013 1014 while (count--) { 1015 __shpcic_mem_write_4(bsh, offset, value); 1016 } 1017 } 1018 1019 /* 1020 * set region 1021 */ 1022 void 1023 shpcic_io_set_region_1(void *v, bus_space_handle_t bsh, 1024 bus_size_t offset, uint8_t value, bus_size_t count) 1025 { 1026 1027 while (count--) { 1028 __shpcic_io_write_1(bsh, offset, value); 1029 offset += 1; 1030 } 1031 } 1032 1033 void 1034 shpcic_io_set_region_2(void *v, bus_space_handle_t bsh, 1035 bus_size_t offset, uint16_t value, bus_size_t count) 1036 { 1037 1038 while (count--) { 1039 __shpcic_io_write_2(bsh, offset, value); 1040 offset += 2; 1041 } 1042 } 1043 1044 void 1045 shpcic_io_set_region_4(void *v, bus_space_handle_t bsh, 1046 bus_size_t offset, uint32_t value, bus_size_t count) 1047 { 1048 1049 while (count--) { 1050 __shpcic_io_write_4(bsh, offset, value); 1051 offset += 4; 1052 } 1053 } 1054 1055 void 1056 shpcic_mem_set_region_1(void *v, bus_space_handle_t bsh, 1057 bus_size_t offset, uint8_t value, bus_size_t count) 1058 { 1059 1060 while (count--) { 1061 __shpcic_mem_write_1(bsh, offset, value); 1062 offset += 1; 1063 } 1064 } 1065 1066 void 1067 shpcic_mem_set_region_2(void *v, bus_space_handle_t bsh, 1068 bus_size_t offset, uint16_t value, bus_size_t count) 1069 { 1070 1071 while (count--) { 1072 __shpcic_mem_write_2(bsh, offset, value); 1073 offset += 2; 1074 } 1075 } 1076 1077 void 1078 shpcic_mem_set_region_4(void *v, bus_space_handle_t bsh, 1079 bus_size_t offset, uint32_t value, bus_size_t count) 1080 { 1081 1082 while (count--) { 1083 __shpcic_mem_write_4(bsh, offset, value); 1084 offset += 4; 1085 } 1086 } 1087 1088 /* 1089 * copy region 1090 */ 1091 void 1092 shpcic_io_copy_region_1(void *v, bus_space_handle_t bsh1, 1093 bus_size_t off1, bus_space_handle_t bsh2, bus_size_t off2, bus_size_t count) 1094 { 1095 u_long addr1 = bsh1 + off1; 1096 u_long addr2 = bsh2 + off2; 1097 uint8_t value; 1098 1099 if (addr1 >= addr2) { /* src after dest: copy forward */ 1100 while (count--) { 1101 value = __shpcic_io_read_1(bsh1, off1); 1102 __shpcic_io_write_1(bsh2, off2, value); 1103 off1 += 1; 1104 off2 += 1; 1105 } 1106 } else { /* dest after src: copy backwards */ 1107 off1 += (count - 1) * 1; 1108 off2 += (count - 1) * 1; 1109 while (count--) { 1110 value = __shpcic_io_read_1(bsh1, off1); 1111 __shpcic_io_write_1(bsh2, off2, value); 1112 off1 -= 1; 1113 off2 -= 1; 1114 } 1115 } 1116 } 1117 1118 void 1119 shpcic_io_copy_region_2(void *v, bus_space_handle_t bsh1, 1120 bus_size_t off1, bus_space_handle_t bsh2, bus_size_t off2, bus_size_t count) 1121 { 1122 u_long addr1 = bsh1 + off1; 1123 u_long addr2 = bsh2 + off2; 1124 uint16_t value; 1125 1126 if (addr1 >= addr2) { /* src after dest: copy forward */ 1127 while (count--) { 1128 value = __shpcic_io_read_2(bsh1, off1); 1129 __shpcic_io_write_2(bsh2, off2, value); 1130 off1 += 2; 1131 off2 += 2; 1132 } 1133 } else { /* dest after src: copy backwards */ 1134 off1 += (count - 1) * 2; 1135 off2 += (count - 1) * 2; 1136 while (count--) { 1137 value = __shpcic_io_read_2(bsh1, off1); 1138 __shpcic_io_write_2(bsh2, off2, value); 1139 off1 -= 2; 1140 off2 -= 2; 1141 } 1142 } 1143 } 1144 1145 void 1146 shpcic_io_copy_region_4(void *v, bus_space_handle_t bsh1, 1147 bus_size_t off1, bus_space_handle_t bsh2, bus_size_t off2, bus_size_t count) 1148 { 1149 u_long addr1 = bsh1 + off1; 1150 u_long addr2 = bsh2 + off2; 1151 uint32_t value; 1152 1153 if (addr1 >= addr2) { /* src after dest: copy forward */ 1154 while (count--) { 1155 value = __shpcic_io_read_4(bsh1, off1); 1156 __shpcic_io_write_4(bsh2, off2, value); 1157 off1 += 4; 1158 off2 += 4; 1159 } 1160 } else { /* dest after src: copy backwards */ 1161 off1 += (count - 1) * 4; 1162 off2 += (count - 1) * 4; 1163 while (count--) { 1164 value = __shpcic_io_read_4(bsh1, off1); 1165 __shpcic_io_write_4(bsh2, off2, value); 1166 off1 -= 4; 1167 off2 -= 4; 1168 } 1169 } 1170 } 1171 1172 void 1173 shpcic_mem_copy_region_1(void *v, bus_space_handle_t bsh1, 1174 bus_size_t off1, bus_space_handle_t bsh2, bus_size_t off2, bus_size_t count) 1175 { 1176 u_long addr1 = bsh1 + off1; 1177 u_long addr2 = bsh2 + off2; 1178 uint8_t value; 1179 1180 if (addr1 >= addr2) { /* src after dest: copy forward */ 1181 while (count--) { 1182 value = __shpcic_mem_read_1(bsh1, off1); 1183 __shpcic_mem_write_1(bsh2, off2, value); 1184 off1 += 1; 1185 off2 += 1; 1186 } 1187 } else { /* dest after src: copy backwards */ 1188 off1 += (count - 1) * 1; 1189 off2 += (count - 1) * 1; 1190 while (count--) { 1191 value = __shpcic_mem_read_1(bsh1, off1); 1192 __shpcic_mem_write_1(bsh2, off2, value); 1193 off1 -= 1; 1194 off2 -= 1; 1195 } 1196 } 1197 } 1198 1199 void 1200 shpcic_mem_copy_region_2(void *v, bus_space_handle_t bsh1, 1201 bus_size_t off1, bus_space_handle_t bsh2, bus_size_t off2, bus_size_t count) 1202 { 1203 u_long addr1 = bsh1 + off1; 1204 u_long addr2 = bsh2 + off2; 1205 uint16_t value; 1206 1207 if (addr1 >= addr2) { /* src after dest: copy forward */ 1208 while (count--) { 1209 value = __shpcic_mem_read_2(bsh1, off1); 1210 __shpcic_mem_write_2(bsh2, off2, value); 1211 off1 += 2; 1212 off2 += 2; 1213 } 1214 } else { /* dest after src: copy backwards */ 1215 off1 += (count - 1) * 2; 1216 off2 += (count - 1) * 2; 1217 while (count--) { 1218 value = __shpcic_mem_read_2(bsh1, off1); 1219 __shpcic_mem_write_2(bsh2, off2, value); 1220 off1 -= 2; 1221 off2 -= 2; 1222 } 1223 } 1224 } 1225 1226 void 1227 shpcic_mem_copy_region_4(void *v, bus_space_handle_t bsh1, 1228 bus_size_t off1, bus_space_handle_t bsh2, bus_size_t off2, bus_size_t count) 1229 { 1230 u_long addr1 = bsh1 + off1; 1231 u_long addr2 = bsh2 + off2; 1232 uint32_t value; 1233 1234 if (addr1 >= addr2) { /* src after dest: copy forward */ 1235 while (count--) { 1236 value = __shpcic_mem_read_4(bsh1, off1); 1237 __shpcic_mem_write_4(bsh2, off2, value); 1238 off1 += 4; 1239 off2 += 4; 1240 } 1241 } else { /* dest after src: copy backwards */ 1242 off1 += (count - 1) * 4; 1243 off2 += (count - 1) * 4; 1244 while (count--) { 1245 value = __shpcic_mem_read_4(bsh1, off1); 1246 __shpcic_mem_write_4(bsh2, off2, value); 1247 off1 -= 4; 1248 off2 -= 4; 1249 } 1250 } 1251 } 1252