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