Home | History | Annotate | Line # | Download | only in dev
shpcic.c revision 1.22
      1 /*	$NetBSD: shpcic.c,v 1.22 2021/08/07 16:19:05 thorpej Exp $	*/
      2 
      3 /*-
      4  * Copyright (C) 2005 NONAKA Kimihiro <nonaka (at) 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.22 2021/08/07 16:19:05 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, CFARGS_NONE);
    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