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