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