xref: /netbsd-src/sys/arch/sh3/dev/shpcic.c (revision 7330f729ccf0bd976a06f95fad452fe774fc7fd1)
1 /*	$NetBSD: shpcic.c,v 1.18 2015/10/02 05:22:52 msaitoh 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.18 2015/10/02 05:22:52 msaitoh 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 <sys/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 	    NULL, 0, EX_NOWAIT);
232 	memext = extent_create("pcimem",
233 	    SH4_PCIC_MEM, SH4_PCIC_MEM + SH4_PCIC_MEM_SIZE - 1,
234 	    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_OKAY | PCI_FLAGS_MEM_OKAY;
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 	if ((unsigned int)reg >= PCI_CONF_SIZE)
299 		return (pcireg_t) -1;
300 
301 	s = splhigh();
302 	_reg_write_4(SH4_PCIPAR, tag | reg);
303 	data = _reg_read_4(SH4_PCIPDR);
304 	_reg_write_4(SH4_PCIPAR, 0);
305 	splx(s);
306 
307 	return data;
308 }
309 
310 void
311 shpcic_conf_write(void *v, pcitag_t tag, int reg, pcireg_t data)
312 {
313 	int s;
314 
315 	if ((unsigned int)reg >= PCI_CONF_SIZE)
316 		return;
317 
318 	s = splhigh();
319 	_reg_write_4(SH4_PCIPAR, tag | reg);
320 	_reg_write_4(SH4_PCIPDR, data);
321 	_reg_write_4(SH4_PCIPAR, 0);
322 	splx(s);
323 }
324 
325 int
326 shpcic_set_intr_priority(int intr, int level)
327 {
328 	int evtcode;
329 
330 	if ((intr != 0) && (intr != 1)) {
331 		return (-1);
332 	}
333 	if ((level < IPL_NONE) || (level > IPL_HIGH)) {
334 		return (-1);
335 	}
336 
337 	if (intr == 0) {
338 		evtcode = SH4_INTEVT_PCIERR;
339 	} else {
340 		evtcode = SH4_INTEVT_PCISERR;
341 	}
342 
343 	intpri_intr_priority(evtcode, shpcic_intr_priority[intr]);
344 	shpcic_intr_priority[intr] = level;
345 
346 	return (0);
347 }
348 
349 void *
350 shpcic_intr_establish(int evtcode, int (*ih_func)(void *), void *ih_arg)
351 {
352 	int level;
353 
354 	switch (evtcode) {
355 	case SH4_INTEVT_PCISERR:
356 		level = shpcic_intr_priority[1];
357 		break;
358 
359 	case SH4_INTEVT_PCIDMA3:
360 	case SH4_INTEVT_PCIDMA2:
361 	case SH4_INTEVT_PCIDMA1:
362 	case SH4_INTEVT_PCIDMA0:
363 	case SH4_INTEVT_PCIPWON:
364 	case SH4_INTEVT_PCIPWDWN:
365 	case SH4_INTEVT_PCIERR:
366 		level = shpcic_intr_priority[0];
367 		break;
368 
369 	default:
370 		printf("shpcic_intr_establish: unknown evtcode = 0x%08x\n",
371 		    evtcode);
372 		return NULL;
373 	}
374 
375 	return intc_intr_establish(evtcode, IST_LEVEL, level, ih_func, ih_arg);
376 }
377 
378 void
379 shpcic_intr_disestablish(void *ih)
380 {
381 
382 	intc_intr_disestablish(ih);
383 }
384 
385 /*
386  * shpcic bus space
387  */
388 int
389 shpcic_iomem_map(void *v, bus_addr_t bpa, bus_size_t size,
390     int flags, bus_space_handle_t *bshp)
391 {
392 
393 	*bshp = (bus_space_handle_t)bpa;
394 
395 	return (0);
396 }
397 
398 void
399 shpcic_iomem_unmap(void *v, bus_space_handle_t bsh, bus_size_t size)
400 {
401 
402 	/* Nothing to do */
403 }
404 
405 int
406 shpcic_iomem_subregion(void *v, bus_space_handle_t bsh,
407     bus_size_t offset, bus_size_t size, bus_space_handle_t *nbshp)
408 {
409 
410 	*nbshp = bsh + offset;
411 
412 	return (0);
413 }
414 
415 int
416 shpcic_iomem_alloc(void *v, bus_addr_t rstart, bus_addr_t rend,
417     bus_size_t size, bus_size_t alignment, bus_size_t boundary, int flags,
418     bus_addr_t *bpap, bus_space_handle_t *bshp)
419 {
420 
421 	*bshp = *bpap = rstart;
422 
423 	return (0);
424 }
425 
426 void
427 shpcic_iomem_free(void *v, bus_space_handle_t bsh, bus_size_t size)
428 {
429 
430 	/* Nothing to do */
431 }
432 
433 paddr_t
434 shpcic_iomem_mmap(void *v, bus_addr_t addr, off_t off, int prot, int flags)
435 {
436 
437 	return (paddr_t)-1;
438 }
439 
440 /*
441  * shpcic bus space io/mem read/write
442  */
443 /* read */
444 static inline uint8_t __shpcic_io_read_1(bus_space_handle_t bsh,
445     bus_size_t offset);
446 static inline uint16_t __shpcic_io_read_2(bus_space_handle_t bsh,
447     bus_size_t offset);
448 static inline uint32_t __shpcic_io_read_4(bus_space_handle_t bsh,
449     bus_size_t offset);
450 static inline uint8_t __shpcic_mem_read_1(bus_space_handle_t bsh,
451     bus_size_t offset);
452 static inline uint16_t __shpcic_mem_read_2(bus_space_handle_t bsh,
453     bus_size_t offset);
454 static inline uint32_t __shpcic_mem_read_4(bus_space_handle_t bsh,
455     bus_size_t offset);
456 
457 static inline uint8_t
458 __shpcic_io_read_1(bus_space_handle_t bsh, bus_size_t offset)
459 {
460 	u_long adr = (u_long)(bsh + offset) & SH4_PCIC_IO_MASK;
461 
462 	return *(volatile uint8_t *)(SH4_PCIC_IO + adr);
463 }
464 
465 static inline uint16_t
466 __shpcic_io_read_2(bus_space_handle_t bsh, bus_size_t offset)
467 {
468 	u_long adr = (u_long)(bsh + offset) & SH4_PCIC_IO_MASK;
469 
470 	return *(volatile uint16_t *)(SH4_PCIC_IO + adr);
471 }
472 
473 static inline uint32_t
474 __shpcic_io_read_4(bus_space_handle_t bsh, bus_size_t offset)
475 {
476 	u_long adr = (u_long)(bsh + offset) & SH4_PCIC_IO_MASK;
477 
478 	return *(volatile uint32_t *)(SH4_PCIC_IO + adr);
479 }
480 
481 static inline uint8_t
482 __shpcic_mem_read_1(bus_space_handle_t bsh, bus_size_t offset)
483 {
484 	u_long adr = (u_long)(bsh + offset) & SH4_PCIC_MEM_MASK;
485 
486 	return *(volatile uint8_t *)(SH4_PCIC_MEM + adr);
487 }
488 
489 static inline uint16_t
490 __shpcic_mem_read_2(bus_space_handle_t bsh, bus_size_t offset)
491 {
492 	u_long adr = (u_long)(bsh + offset) & SH4_PCIC_MEM_MASK;
493 
494 	return *(volatile uint16_t *)(SH4_PCIC_MEM + adr);
495 }
496 
497 static inline uint32_t
498 __shpcic_mem_read_4(bus_space_handle_t bsh, bus_size_t offset)
499 {
500 	u_long adr = (u_long)(bsh + offset) & SH4_PCIC_MEM_MASK;
501 
502 	return *(volatile uint32_t *)(SH4_PCIC_MEM + adr);
503 }
504 
505 /*
506  * read single
507  */
508 uint8_t
509 shpcic_io_read_1(void *v, bus_space_handle_t bsh, bus_size_t offset)
510 {
511 	uint8_t value;
512 
513 	value = __shpcic_io_read_1(bsh, offset);
514 
515 	return value;
516 }
517 
518 uint16_t
519 shpcic_io_read_2(void *v, bus_space_handle_t bsh, bus_size_t offset)
520 {
521 	uint16_t value;
522 
523 	value = __shpcic_io_read_2(bsh, offset);
524 
525 	return value;
526 }
527 
528 uint32_t
529 shpcic_io_read_4(void *v, bus_space_handle_t bsh, bus_size_t offset)
530 {
531 	uint32_t value;
532 
533 	value = __shpcic_io_read_4(bsh, offset);
534 
535 	return value;
536 }
537 
538 uint8_t
539 shpcic_mem_read_1(void *v, bus_space_handle_t bsh, bus_size_t offset)
540 {
541 	uint8_t value;
542 
543 	value = __shpcic_mem_read_1(bsh, offset);
544 
545 	return value;
546 }
547 
548 uint16_t
549 shpcic_mem_read_2(void *v, bus_space_handle_t bsh, bus_size_t offset)
550 {
551 	uint16_t value;
552 
553 	value = __shpcic_mem_read_2(bsh, offset);
554 
555 	return value;
556 }
557 
558 uint32_t
559 shpcic_mem_read_4(void *v, bus_space_handle_t bsh, bus_size_t offset)
560 {
561 	uint32_t value;
562 
563 	value = __shpcic_mem_read_4(bsh, offset);
564 
565 	return value;
566 }
567 
568 /*
569  * read multi
570  */
571 void
572 shpcic_io_read_multi_1(void *v, bus_space_handle_t bsh,
573     bus_size_t offset, uint8_t *addr, bus_size_t count)
574 {
575 
576 	while (count--) {
577 		*addr++ = __shpcic_io_read_1(bsh, offset);
578 	}
579 }
580 
581 void
582 shpcic_io_read_multi_2(void *v, bus_space_handle_t bsh,
583     bus_size_t offset, uint16_t *addr, bus_size_t count)
584 {
585 
586 	while (count--) {
587 		*addr++ = __shpcic_io_read_2(bsh, offset);
588 	}
589 }
590 
591 void
592 shpcic_io_read_multi_4(void *v, bus_space_handle_t bsh,
593     bus_size_t offset, uint32_t *addr, bus_size_t count)
594 {
595 
596 	while (count--) {
597 		*addr++ = __shpcic_io_read_4(bsh, offset);
598 	}
599 }
600 
601 void
602 shpcic_mem_read_multi_1(void *v, bus_space_handle_t bsh,
603     bus_size_t offset, uint8_t *addr, bus_size_t count)
604 {
605 
606 	while (count--) {
607 		*addr++ = __shpcic_mem_read_1(bsh, offset);
608 	}
609 }
610 
611 void
612 shpcic_mem_read_multi_2(void *v, bus_space_handle_t bsh,
613     bus_size_t offset, uint16_t *addr, bus_size_t count)
614 {
615 
616 	while (count--) {
617 		*addr++ = __shpcic_mem_read_2(bsh, offset);
618 	}
619 }
620 
621 void
622 shpcic_mem_read_multi_4(void *v, bus_space_handle_t bsh,
623     bus_size_t offset, uint32_t *addr, bus_size_t count)
624 {
625 
626 	while (count--) {
627 		*addr++ = __shpcic_mem_read_4(bsh, offset);
628 	}
629 }
630 
631 /*
632  *
633  * read region
634  */
635 void
636 shpcic_io_read_region_1(void *v, bus_space_handle_t bsh,
637     bus_size_t offset, uint8_t *addr, bus_size_t count)
638 {
639 
640 	while (count--) {
641 		*addr++ = __shpcic_io_read_1(bsh, offset);
642 		offset += 1;
643 	}
644 }
645 
646 void
647 shpcic_io_read_region_2(void *v, bus_space_handle_t bsh,
648     bus_size_t offset, uint16_t *addr, bus_size_t count)
649 {
650 
651 	while (count--) {
652 		*addr++ = __shpcic_io_read_2(bsh, offset);
653 		offset += 2;
654 	}
655 }
656 
657 void
658 shpcic_io_read_region_4(void *v, bus_space_handle_t bsh,
659     bus_size_t offset, uint32_t *addr, bus_size_t count)
660 {
661 
662 	while (count--) {
663 		*addr++ = __shpcic_io_read_4(bsh, offset);
664 		offset += 4;
665 	}
666 }
667 
668 void
669 shpcic_mem_read_region_1(void *v, bus_space_handle_t bsh,
670     bus_size_t offset, uint8_t *addr, bus_size_t count)
671 {
672 
673 	while (count--) {
674 		*addr++ = __shpcic_mem_read_1(bsh, offset);
675 		offset += 1;
676 	}
677 }
678 
679 void
680 shpcic_mem_read_region_2(void *v, bus_space_handle_t bsh,
681     bus_size_t offset, uint16_t *addr, bus_size_t count)
682 {
683 
684 	while (count--) {
685 		*addr++ = __shpcic_mem_read_2(bsh, offset);
686 		offset += 2;
687 	}
688 }
689 
690 void
691 shpcic_mem_read_region_4(void *v, bus_space_handle_t bsh,
692     bus_size_t offset, uint32_t *addr, bus_size_t count)
693 {
694 
695 	while (count--) {
696 		*addr++ = __shpcic_mem_read_4(bsh, offset);
697 		offset += 4;
698 	}
699 }
700 
701 /* write */
702 static inline void __shpcic_io_write_1(bus_space_handle_t bsh,
703     bus_size_t offset, uint8_t value);
704 static inline void __shpcic_io_write_2(bus_space_handle_t bsh,
705     bus_size_t offset, uint16_t value);
706 static inline void __shpcic_io_write_4(bus_space_handle_t bsh,
707     bus_size_t offset, uint32_t value);
708 static inline void __shpcic_mem_write_1(bus_space_handle_t bsh,
709     bus_size_t offset, uint8_t value);
710 static inline void __shpcic_mem_write_2(bus_space_handle_t bsh,
711     bus_size_t offset, uint16_t value);
712 static inline void __shpcic_mem_write_4(bus_space_handle_t bsh,
713     bus_size_t offset, uint32_t value);
714 
715 static inline void
716 __shpcic_io_write_1(bus_space_handle_t bsh, bus_size_t offset,
717     uint8_t value)
718 {
719 	u_long adr = (u_long)(bsh + offset) & SH4_PCIC_IO_MASK;
720 
721 	*(volatile uint8_t *)(SH4_PCIC_IO + adr) = value;
722 }
723 
724 static inline void
725 __shpcic_io_write_2(bus_space_handle_t bsh, bus_size_t offset,
726     uint16_t value)
727 {
728 	u_long adr = (u_long)(bsh + offset) & SH4_PCIC_IO_MASK;
729 
730 	*(volatile uint16_t *)(SH4_PCIC_IO + adr) = value;
731 }
732 
733 static inline void
734 __shpcic_io_write_4(bus_space_handle_t bsh, bus_size_t offset,
735     uint32_t value)
736 {
737 	u_long adr = (u_long)(bsh + offset) & SH4_PCIC_IO_MASK;
738 
739 	*(volatile uint32_t *)(SH4_PCIC_IO + adr) = value;
740 }
741 
742 static inline void
743 __shpcic_mem_write_1(bus_space_handle_t bsh, bus_size_t offset,
744     uint8_t value)
745 {
746 	u_long adr = (u_long)(bsh + offset) & SH4_PCIC_MEM_MASK;
747 
748 	*(volatile uint8_t *)(SH4_PCIC_MEM + adr) = value;
749 }
750 
751 static inline void
752 __shpcic_mem_write_2(bus_space_handle_t bsh, bus_size_t offset,
753     uint16_t value)
754 {
755 	u_long adr = (u_long)(bsh + offset) & SH4_PCIC_MEM_MASK;
756 
757 	*(volatile uint16_t *)(SH4_PCIC_MEM + adr) = value;
758 }
759 
760 static inline void
761 __shpcic_mem_write_4(bus_space_handle_t bsh, bus_size_t offset,
762     uint32_t value)
763 {
764 	u_long adr = (u_long)(bsh + offset) & SH4_PCIC_MEM_MASK;
765 
766 	*(volatile uint32_t *)(SH4_PCIC_MEM + adr) = value;
767 }
768 
769 /*
770  * write single
771  */
772 void
773 shpcic_io_write_1(void *v, bus_space_handle_t bsh,
774     bus_size_t offset, uint8_t value)
775 {
776 
777 	__shpcic_io_write_1(bsh, offset, value);
778 }
779 
780 void
781 shpcic_io_write_2(void *v, bus_space_handle_t bsh,
782     bus_size_t offset, uint16_t value)
783 {
784 
785 	__shpcic_io_write_2(bsh, offset, value);
786 }
787 
788 void
789 shpcic_io_write_4(void *v, bus_space_handle_t bsh,
790     bus_size_t offset, uint32_t value)
791 {
792 
793 	__shpcic_io_write_4(bsh, offset, value);
794 }
795 
796 void
797 shpcic_mem_write_1(void *v, bus_space_handle_t bsh,
798     bus_size_t offset, uint8_t value)
799 {
800 
801 	__shpcic_mem_write_1(bsh, offset, value);
802 }
803 
804 void
805 shpcic_mem_write_2(void *v, bus_space_handle_t bsh,
806     bus_size_t offset, uint16_t value)
807 {
808 
809 	__shpcic_mem_write_2(bsh, offset, value);
810 }
811 
812 void
813 shpcic_mem_write_4(void *v, bus_space_handle_t bsh,
814     bus_size_t offset, uint32_t value)
815 {
816 
817 	__shpcic_mem_write_4(bsh, offset, value);
818 }
819 
820 /*
821  * write multi
822  */
823 void
824 shpcic_io_write_multi_1(void *v, bus_space_handle_t bsh,
825     bus_size_t offset, const uint8_t *addr, bus_size_t count)
826 {
827 
828 	while (count--) {
829 		__shpcic_io_write_1(bsh, offset, *addr++);
830 	}
831 }
832 
833 void
834 shpcic_io_write_multi_2(void *v, bus_space_handle_t bsh,
835     bus_size_t offset, const uint16_t *addr, bus_size_t count)
836 {
837 
838 	while (count--) {
839 		__shpcic_io_write_2(bsh, offset, *addr++);
840 	}
841 }
842 
843 void
844 shpcic_io_write_multi_4(void *v, bus_space_handle_t bsh,
845     bus_size_t offset, const uint32_t *addr, bus_size_t count)
846 {
847 
848 	while (count--) {
849 		__shpcic_io_write_4(bsh, offset, *addr++);
850 	}
851 }
852 
853 void
854 shpcic_mem_write_multi_1(void *v, bus_space_handle_t bsh,
855     bus_size_t offset, const uint8_t *addr, bus_size_t count)
856 {
857 
858 	while (count--) {
859 		__shpcic_mem_write_1(bsh, offset, *addr++);
860 	}
861 }
862 
863 void
864 shpcic_mem_write_multi_2(void *v, bus_space_handle_t bsh,
865     bus_size_t offset, const uint16_t *addr, bus_size_t count)
866 {
867 
868 	while (count--) {
869 		__shpcic_mem_write_2(bsh, offset, *addr++);
870 	}
871 }
872 
873 void
874 shpcic_mem_write_multi_4(void *v, bus_space_handle_t bsh,
875     bus_size_t offset, const uint32_t *addr, bus_size_t count)
876 {
877 
878 	while (count--) {
879 		__shpcic_mem_write_4(bsh, offset, *addr++);
880 	}
881 }
882 
883 /*
884  * write region
885  */
886 void
887 shpcic_io_write_region_1(void *v, bus_space_handle_t bsh,
888     bus_size_t offset, const uint8_t *addr, bus_size_t count)
889 {
890 
891 	while (count--) {
892 		__shpcic_io_write_1(bsh, offset, *addr++);
893 		offset += 1;
894 	}
895 }
896 
897 void
898 shpcic_io_write_region_2(void *v, bus_space_handle_t bsh,
899     bus_size_t offset, const uint16_t *addr, bus_size_t count)
900 {
901 
902 	while (count--) {
903 		__shpcic_io_write_2(bsh, offset, *addr++);
904 		offset += 2;
905 	}
906 }
907 
908 void
909 shpcic_io_write_region_4(void *v, bus_space_handle_t bsh,
910     bus_size_t offset, const uint32_t *addr, bus_size_t count)
911 {
912 
913 	while (count--) {
914 		__shpcic_io_write_4(bsh, offset, *addr++);
915 		offset += 4;
916 	}
917 }
918 
919 void
920 shpcic_mem_write_region_1(void *v, bus_space_handle_t bsh,
921     bus_size_t offset, const uint8_t *addr, bus_size_t count)
922 {
923 
924 	while (count--) {
925 		__shpcic_mem_write_1(bsh, offset, *addr++);
926 		offset += 1;
927 	}
928 }
929 
930 void
931 shpcic_mem_write_region_2(void *v, bus_space_handle_t bsh,
932     bus_size_t offset, const uint16_t *addr, bus_size_t count)
933 {
934 
935 	while (count--) {
936 		__shpcic_mem_write_2(bsh, offset, *addr++);
937 		offset += 2;
938 	}
939 }
940 
941 void
942 shpcic_mem_write_region_4(void *v, bus_space_handle_t bsh,
943     bus_size_t offset, const uint32_t *addr, bus_size_t count)
944 {
945 
946 	while (count--) {
947 		__shpcic_mem_write_4(bsh, offset, *addr++);
948 		offset += 4;
949 	}
950 }
951 
952 /*
953  * set multi
954  */
955 void
956 shpcic_io_set_multi_1(void *v, bus_space_handle_t bsh,
957     bus_size_t offset, uint8_t value, bus_size_t count)
958 {
959 
960 	while (count--) {
961 		__shpcic_io_write_1(bsh, offset, value);
962 	}
963 }
964 
965 void
966 shpcic_io_set_multi_2(void *v, bus_space_handle_t bsh,
967     bus_size_t offset, uint16_t value, bus_size_t count)
968 {
969 
970 	while (count--) {
971 		__shpcic_io_write_2(bsh, offset, value);
972 	}
973 }
974 
975 void
976 shpcic_io_set_multi_4(void *v, bus_space_handle_t bsh,
977     bus_size_t offset, uint32_t value, bus_size_t count)
978 {
979 
980 	while (count--) {
981 		__shpcic_io_write_4(bsh, offset, value);
982 	}
983 }
984 
985 void
986 shpcic_mem_set_multi_1(void *v, bus_space_handle_t bsh,
987     bus_size_t offset, uint8_t value, bus_size_t count)
988 {
989 
990 	while (count--) {
991 		__shpcic_mem_write_1(bsh, offset, value);
992 	}
993 }
994 
995 void
996 shpcic_mem_set_multi_2(void *v, bus_space_handle_t bsh,
997     bus_size_t offset, uint16_t value, bus_size_t count)
998 {
999 
1000 	while (count--) {
1001 		__shpcic_mem_write_2(bsh, offset, value);
1002 	}
1003 }
1004 
1005 void
1006 shpcic_mem_set_multi_4(void *v, bus_space_handle_t bsh,
1007     bus_size_t offset, uint32_t value, bus_size_t count)
1008 {
1009 
1010 	while (count--) {
1011 		__shpcic_mem_write_4(bsh, offset, value);
1012 	}
1013 }
1014 
1015 /*
1016  * set region
1017  */
1018 void
1019 shpcic_io_set_region_1(void *v, bus_space_handle_t bsh,
1020     bus_size_t offset, uint8_t value, bus_size_t count)
1021 {
1022 
1023 	while (count--) {
1024 		__shpcic_io_write_1(bsh, offset, value);
1025 		offset += 1;
1026 	}
1027 }
1028 
1029 void
1030 shpcic_io_set_region_2(void *v, bus_space_handle_t bsh,
1031     bus_size_t offset, uint16_t value, bus_size_t count)
1032 {
1033 
1034 	while (count--) {
1035 		__shpcic_io_write_2(bsh, offset, value);
1036 		offset += 2;
1037 	}
1038 }
1039 
1040 void
1041 shpcic_io_set_region_4(void *v, bus_space_handle_t bsh,
1042     bus_size_t offset, uint32_t value, bus_size_t count)
1043 {
1044 
1045 	while (count--) {
1046 		__shpcic_io_write_4(bsh, offset, value);
1047 		offset += 4;
1048 	}
1049 }
1050 
1051 void
1052 shpcic_mem_set_region_1(void *v, bus_space_handle_t bsh,
1053     bus_size_t offset, uint8_t value, bus_size_t count)
1054 {
1055 
1056 	while (count--) {
1057 		__shpcic_mem_write_1(bsh, offset, value);
1058 		offset += 1;
1059 	}
1060 }
1061 
1062 void
1063 shpcic_mem_set_region_2(void *v, bus_space_handle_t bsh,
1064     bus_size_t offset, uint16_t value, bus_size_t count)
1065 {
1066 
1067 	while (count--) {
1068 		__shpcic_mem_write_2(bsh, offset, value);
1069 		offset += 2;
1070 	}
1071 }
1072 
1073 void
1074 shpcic_mem_set_region_4(void *v, bus_space_handle_t bsh,
1075     bus_size_t offset, uint32_t value, bus_size_t count)
1076 {
1077 
1078 	while (count--) {
1079 		__shpcic_mem_write_4(bsh, offset, value);
1080 		offset += 4;
1081 	}
1082 }
1083 
1084 /*
1085  * copy region
1086  */
1087 void
1088 shpcic_io_copy_region_1(void *v, bus_space_handle_t bsh1,
1089     bus_size_t off1, bus_space_handle_t bsh2, bus_size_t off2, bus_size_t count)
1090 {
1091 	u_long addr1 = bsh1 + off1;
1092 	u_long addr2 = bsh2 + off2;
1093 	uint8_t value;
1094 
1095 	if (addr1 >= addr2) {	/* src after dest: copy forward */
1096 		while (count--) {
1097 			value = __shpcic_io_read_1(bsh1, off1);
1098 			__shpcic_io_write_1(bsh2, off2, value);
1099 			off1 += 1;
1100 			off2 += 1;
1101 		}
1102 	} else {		/* dest after src: copy backwards */
1103 		off1 += (count - 1) * 1;
1104 		off2 += (count - 1) * 1;
1105 		while (count--) {
1106 			value = __shpcic_io_read_1(bsh1, off1);
1107 			__shpcic_io_write_1(bsh2, off2, value);
1108 			off1 -= 1;
1109 			off2 -= 1;
1110 		}
1111 	}
1112 }
1113 
1114 void
1115 shpcic_io_copy_region_2(void *v, bus_space_handle_t bsh1,
1116     bus_size_t off1, bus_space_handle_t bsh2, bus_size_t off2, bus_size_t count)
1117 {
1118 	u_long addr1 = bsh1 + off1;
1119 	u_long addr2 = bsh2 + off2;
1120 	uint16_t value;
1121 
1122 	if (addr1 >= addr2) {	/* src after dest: copy forward */
1123 		while (count--) {
1124 			value = __shpcic_io_read_2(bsh1, off1);
1125 			__shpcic_io_write_2(bsh2, off2, value);
1126 			off1 += 2;
1127 			off2 += 2;
1128 		}
1129 	} else {		/* dest after src: copy backwards */
1130 		off1 += (count - 1) * 2;
1131 		off2 += (count - 1) * 2;
1132 		while (count--) {
1133 			value = __shpcic_io_read_2(bsh1, off1);
1134 			__shpcic_io_write_2(bsh2, off2, value);
1135 			off1 -= 2;
1136 			off2 -= 2;
1137 		}
1138 	}
1139 }
1140 
1141 void
1142 shpcic_io_copy_region_4(void *v, bus_space_handle_t bsh1,
1143     bus_size_t off1, bus_space_handle_t bsh2, bus_size_t off2, bus_size_t count)
1144 {
1145 	u_long addr1 = bsh1 + off1;
1146 	u_long addr2 = bsh2 + off2;
1147 	uint32_t value;
1148 
1149 	if (addr1 >= addr2) {	/* src after dest: copy forward */
1150 		while (count--) {
1151 			value = __shpcic_io_read_4(bsh1, off1);
1152 			__shpcic_io_write_4(bsh2, off2, value);
1153 			off1 += 4;
1154 			off2 += 4;
1155 		}
1156 	} else {		/* dest after src: copy backwards */
1157 		off1 += (count - 1) * 4;
1158 		off2 += (count - 1) * 4;
1159 		while (count--) {
1160 			value = __shpcic_io_read_4(bsh1, off1);
1161 			__shpcic_io_write_4(bsh2, off2, value);
1162 			off1 -= 4;
1163 			off2 -= 4;
1164 		}
1165 	}
1166 }
1167 
1168 void
1169 shpcic_mem_copy_region_1(void *v, bus_space_handle_t bsh1,
1170     bus_size_t off1, bus_space_handle_t bsh2, bus_size_t off2, bus_size_t count)
1171 {
1172 	u_long addr1 = bsh1 + off1;
1173 	u_long addr2 = bsh2 + off2;
1174 	uint8_t value;
1175 
1176 	if (addr1 >= addr2) {	/* src after dest: copy forward */
1177 		while (count--) {
1178 			value = __shpcic_mem_read_1(bsh1, off1);
1179 			__shpcic_mem_write_1(bsh2, off2, value);
1180 			off1 += 1;
1181 			off2 += 1;
1182 		}
1183 	} else {		/* dest after src: copy backwards */
1184 		off1 += (count - 1) * 1;
1185 		off2 += (count - 1) * 1;
1186 		while (count--) {
1187 			value = __shpcic_mem_read_1(bsh1, off1);
1188 			__shpcic_mem_write_1(bsh2, off2, value);
1189 			off1 -= 1;
1190 			off2 -= 1;
1191 		}
1192 	}
1193 }
1194 
1195 void
1196 shpcic_mem_copy_region_2(void *v, bus_space_handle_t bsh1,
1197     bus_size_t off1, bus_space_handle_t bsh2, bus_size_t off2, bus_size_t count)
1198 {
1199 	u_long addr1 = bsh1 + off1;
1200 	u_long addr2 = bsh2 + off2;
1201 	uint16_t value;
1202 
1203 	if (addr1 >= addr2) {	/* src after dest: copy forward */
1204 		while (count--) {
1205 			value = __shpcic_mem_read_2(bsh1, off1);
1206 			__shpcic_mem_write_2(bsh2, off2, value);
1207 			off1 += 2;
1208 			off2 += 2;
1209 		}
1210 	} else {		/* dest after src: copy backwards */
1211 		off1 += (count - 1) * 2;
1212 		off2 += (count - 1) * 2;
1213 		while (count--) {
1214 			value = __shpcic_mem_read_2(bsh1, off1);
1215 			__shpcic_mem_write_2(bsh2, off2, value);
1216 			off1 -= 2;
1217 			off2 -= 2;
1218 		}
1219 	}
1220 }
1221 
1222 void
1223 shpcic_mem_copy_region_4(void *v, bus_space_handle_t bsh1,
1224     bus_size_t off1, bus_space_handle_t bsh2, bus_size_t off2, bus_size_t count)
1225 {
1226 	u_long addr1 = bsh1 + off1;
1227 	u_long addr2 = bsh2 + off2;
1228 	uint32_t value;
1229 
1230 	if (addr1 >= addr2) {	/* src after dest: copy forward */
1231 		while (count--) {
1232 			value = __shpcic_mem_read_4(bsh1, off1);
1233 			__shpcic_mem_write_4(bsh2, off2, value);
1234 			off1 += 4;
1235 			off2 += 4;
1236 		}
1237 	} else {		/* dest after src: copy backwards */
1238 		off1 += (count - 1) * 4;
1239 		off2 += (count - 1) * 4;
1240 		while (count--) {
1241 			value = __shpcic_mem_read_4(bsh1, off1);
1242 			__shpcic_mem_write_4(bsh2, off2, value);
1243 			off1 -= 4;
1244 			off2 -= 4;
1245 		}
1246 	}
1247 }
1248