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