1 /* $NetBSD: marvell_machdep.c,v 1.36 2019/07/16 14:41:47 skrll Exp $ */ 2 /* 3 * Copyright (c) 2007, 2008, 2010 KIYOHARA Takashi 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 19 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 21 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 23 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 24 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 * POSSIBILITY OF SUCH DAMAGE. 26 */ 27 #include <sys/cdefs.h> 28 __KERNEL_RCSID(0, "$NetBSD: marvell_machdep.c,v 1.36 2019/07/16 14:41:47 skrll Exp $"); 29 30 #include "opt_arm_debug.h" 31 #include "opt_console.h" 32 #include "opt_evbarm_boardtype.h" 33 #include "opt_ddb.h" 34 #include "opt_pci.h" 35 #include "opt_mvsoc.h" 36 #include "com.h" 37 #include "gtpci.h" 38 #include "mvpex.h" 39 40 #include <sys/param.h> 41 #include <sys/kernel.h> 42 #include <sys/reboot.h> 43 #include <sys/systm.h> 44 #include <sys/termios.h> 45 46 #include <prop/proplib.h> 47 48 #include <dev/cons.h> 49 #include <dev/md.h> 50 51 #include <dev/marvell/marvellreg.h> 52 #include <dev/marvell/marvellvar.h> 53 #include <dev/pci/pcireg.h> 54 #include <dev/pci/pcivar.h> 55 56 #include <machine/autoconf.h> 57 #include <machine/bootconfig.h> 58 #include <machine/pci_machdep.h> 59 60 #include <uvm/uvm_extern.h> 61 62 #include <arm/db_machdep.h> 63 #include <arm/undefined.h> 64 #include <arm/arm32/machdep.h> 65 66 #include <arm/marvell/mvsocreg.h> 67 #include <arm/marvell/mvsocvar.h> 68 #include <arm/marvell/orionreg.h> 69 #include <arm/marvell/kirkwoodreg.h> 70 #include <arm/marvell/mv78xx0reg.h> 71 #include <arm/marvell/dovereg.h> 72 #include <arm/marvell/armadaxpreg.h> 73 #include <arm/marvell/armadaxpvar.h> 74 #include <arm/marvell/mvsocgppvar.h> 75 76 #include <evbarm/marvell/marvellreg.h> 77 #include <evbarm/marvell/marvellvar.h> 78 79 #include <ddb/db_extern.h> 80 #include <ddb/db_sym.h> 81 82 #include "ksyms.h" 83 84 85 /* 86 * The range 0xc2000000 - 0xdfffffff is available for kernel VM space 87 * Core-logic registers and I/O mappings occupy 0xfe000000 - 0xffffffff 88 */ 89 #if (KERNEL_BASE & 0xf0000000) == 0x80000000 90 #define KERNEL_VM_BASE (KERNEL_BASE + 0x42000000) 91 #else 92 #define KERNEL_VM_BASE (KERNEL_BASE + 0x02000000) 93 #endif 94 #define KERNEL_VM_SIZE 0x1e000000 95 96 BootConfig bootconfig; /* Boot config storage */ 97 static char bootargs[MAX_BOOT_STRING]; 98 char *boot_args = NULL; 99 100 extern int KERNEL_BASE_phys[]; 101 extern char _end[]; 102 103 /* 104 * Macros to translate between physical and virtual for a subset of the 105 * kernel address space. *Not* for general use. 106 */ 107 #define KERNEL_BASE_PHYS physical_start 108 109 110 #include "com.h" 111 #if NCOM > 0 112 #include <dev/ic/comreg.h> 113 #include <dev/ic/comvar.h> 114 #endif 115 116 #ifndef CONSPEED 117 #define CONSPEED B115200 /* It's a setting of the default of u-boot */ 118 #endif 119 #ifndef CONMODE 120 #define CONMODE ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8) /* 8N1 */ 121 122 int comcnspeed = CONSPEED; 123 int comcnmode = CONMODE; 124 #endif 125 126 #include "opt_kgdb.h" 127 #ifdef KGDB 128 #include <sys/kgdb.h> 129 #endif 130 131 static void marvell_device_register(device_t, void *); 132 #if NGTPCI > 0 || NMVPEX > 0 133 static void marvell_startend_by_tag(int, uint64_t *, uint64_t *); 134 #endif 135 136 static void 137 marvell_fixup_mbus_pex(int memtag, int iotag) 138 { 139 uint32_t target, attr; 140 int window; 141 142 /* Reset PCI-Express space to window register. */ 143 window = mvsoc_target(memtag, &target, &attr, NULL, NULL); 144 write_mlmbreg(MVSOC_MLMB_WCR(window), 145 MVSOC_MLMB_WCR_WINEN | 146 MVSOC_MLMB_WCR_TARGET(target) | 147 MVSOC_MLMB_WCR_ATTR(attr) | 148 MVSOC_MLMB_WCR_SIZE(MARVELL_PEXMEM_SIZE)); 149 write_mlmbreg(MVSOC_MLMB_WBR(window), 150 MARVELL_PEXMEM_PBASE & MVSOC_MLMB_WBR_BASE_MASK); 151 #ifdef PCI_NETBSD_CONFIGURE 152 if (window < nremap) { 153 write_mlmbreg(MVSOC_MLMB_WRLR(window), 154 MARVELL_PEXMEM_PBASE & MVSOC_MLMB_WRLR_REMAP_MASK); 155 write_mlmbreg(MVSOC_MLMB_WRHR(window), 0); 156 } 157 #endif 158 window = mvsoc_target(iotag, &target, &attr, NULL, NULL); 159 write_mlmbreg(MVSOC_MLMB_WCR(window), 160 MVSOC_MLMB_WCR_WINEN | 161 MVSOC_MLMB_WCR_TARGET(target) | 162 MVSOC_MLMB_WCR_ATTR(attr) | 163 MVSOC_MLMB_WCR_SIZE(MARVELL_PEXIO_SIZE)); 164 write_mlmbreg(MVSOC_MLMB_WBR(window), 165 MARVELL_PEXIO_PBASE & MVSOC_MLMB_WBR_BASE_MASK); 166 #ifdef PCI_NETBSD_CONFIGURE 167 if (window < nremap) { 168 write_mlmbreg(MVSOC_MLMB_WRLR(window), 169 MARVELL_PEXIO_PBASE & MVSOC_MLMB_WRLR_REMAP_MASK); 170 write_mlmbreg(MVSOC_MLMB_WRHR(window), 0); 171 } 172 #endif 173 } 174 175 #if defined(ORION) || defined(KIRKWOOD) || defined(MV78XX0) || defined(DOVE) 176 static void 177 marvell_system_reset(void) 178 { 179 /* unmask soft reset */ 180 write_mlmbreg(MVSOC_MLMB_RSTOUTNMASKR, 181 MVSOC_MLMB_RSTOUTNMASKR_SOFTRSTOUTEN); 182 /* assert soft reset */ 183 write_mlmbreg(MVSOC_MLMB_SSRR, MVSOC_MLMB_SSRR_SYSTEMSOFTRST); 184 185 /* if we're still running, jump to the reset address */ 186 cpu_reset_address = 0; 187 cpu_reset_address_paddr = 0xffff0000; 188 cpu_reset(); 189 /*NOTREACHED*/ 190 } 191 192 static void 193 marvell_fixup_mbus(int memtag, int iotag) 194 { 195 /* assume u-boot initializes mbus registers correctly */ 196 197 /* set marvell common PEX params */ 198 marvell_fixup_mbus_pex(memtag, iotag); 199 200 /* other configurations? */ 201 } 202 #endif 203 204 205 #if defined(ARMADAXP) 206 static void 207 armadaxp_system_reset(void) 208 { 209 extern vaddr_t misc_base; 210 211 #define write_miscreg(r, v) (*(volatile uint32_t *)(misc_base + (r)) = (v)) 212 213 /* Unmask soft reset */ 214 write_miscreg(ARMADAXP_MISC_RSTOUTNMASKR, 215 ARMADAXP_MISC_RSTOUTNMASKR_GLOBALSOFTRSTOUTEN); 216 /* Assert soft reset */ 217 write_miscreg(ARMADAXP_MISC_SSRR, ARMADAXP_MISC_SSRR_GLOBALSOFTRST); 218 219 while (1); 220 221 /*NOTREACHED*/ 222 } 223 224 static void 225 armadaxp_fixup_mbus(int memtag, int iotag) 226 { 227 /* force set SoC default parameters */ 228 armadaxp_init_mbus(); 229 230 /* set marvell common PEX params */ 231 marvell_fixup_mbus_pex(memtag, iotag); 232 233 /* other configurations? */ 234 } 235 #endif 236 237 238 static inline pd_entry_t * 239 read_ttb(void) 240 { 241 242 return (pd_entry_t *)(armreg_ttbr_read() & ~((1<<14)-1)); 243 } 244 245 /* 246 * Static device mappings. These peripheral registers are mapped at 247 * fixed virtual addresses very early in initarm() so that we can use 248 * them while booting the kernel, and stay at the same address 249 * throughout whole kernel's life time. 250 * 251 * We use this table twice; once with bootstrap page table, and once 252 * with kernel's page table which we build up in initarm(). 253 * 254 * Since we map these registers into the bootstrap page table using 255 * pmap_devmap_bootstrap() which calls pmap_map_chunk(), we map 256 * registers segment-aligned and segment-rounded in order to avoid 257 * using the 2nd page tables. 258 */ 259 #define _A(a) ((a) & ~L1_S_OFFSET) 260 #define _S(s) (((s) + L1_S_SIZE - 1) & ~(L1_S_SIZE-1)) 261 262 static struct pmap_devmap marvell_devmap[] = { 263 { 264 MARVELL_INTERREGS_VBASE, 265 _A(MARVELL_INTERREGS_PBASE), 266 _S(MVSOC_INTERREGS_SIZE), 267 VM_PROT_READ|VM_PROT_WRITE, 268 PTE_NOCACHE, 269 }, 270 271 { 0, 0, 0, 0, 0 } 272 }; 273 274 extern uint32_t *u_boot_args[]; 275 276 /* 277 * vaddr_t initarm(...) 278 * 279 * Initial entry point on startup. This gets called before main() is 280 * entered. 281 * It should be responsible for setting up everything that must be 282 * in place when main is called. 283 * This includes 284 * Taking a copy of the boot configuration structure. 285 * Initialising the physical console so characters can be printed. 286 * Setting up page tables for the kernel 287 * Relocating the kernel to the bottom of physical memory 288 */ 289 vaddr_t 290 initarm(void *arg) 291 { 292 int cs, cs_end, memtag = 0, iotag = 0; 293 294 mvsoc_bootstrap(MARVELL_INTERREGS_VBASE); 295 296 /* 297 * Heads up ... Setup the CPU / MMU / TLB functions 298 */ 299 if (set_cpufuncs()) 300 panic("cpu not recognized!"); 301 302 /* map some peripheral registers */ 303 pmap_devmap_bootstrap((vaddr_t)read_ttb(), marvell_devmap); 304 305 /* 306 * U-Boot doesn't use the virtual memory. 307 * 308 * Physical Address Range Description 309 * ----------------------- ---------------------------------- 310 * 0x00000000 - 0x0fffffff SDRAM Bank 0 (max 256MB) 311 * 0x10000000 - 0x1fffffff SDRAM Bank 1 (max 256MB) 312 * 0x20000000 - 0x2fffffff SDRAM Bank 2 (max 256MB) 313 * 0x30000000 - 0x3fffffff SDRAM Bank 3 (max 256MB) 314 * 0xf1000000 - 0xf10fffff SoC Internal Registers 315 */ 316 317 cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT); 318 319 /* Get ready for splfoo() */ 320 switch (mvsoc_model()) { 321 #ifdef ORION 322 case MARVELL_ORION_1_88F1181: 323 case MARVELL_ORION_1_88F5082: 324 case MARVELL_ORION_1_88F5180N: 325 case MARVELL_ORION_1_88F5181: 326 case MARVELL_ORION_1_88F5182: 327 case MARVELL_ORION_1_88F6082: 328 case MARVELL_ORION_1_88F6183: 329 case MARVELL_ORION_1_88W8660: 330 case MARVELL_ORION_2_88F1281: 331 case MARVELL_ORION_2_88F5281: 332 cpu_reset_address = marvell_system_reset; 333 334 orion_bootstrap(MARVELL_INTERREGS_VBASE); 335 336 memtag = ORION_TAG_PEX0_MEM; 337 iotag = ORION_TAG_PEX0_IO; 338 nwindow = ORION_MLMB_NWINDOW; 339 nremap = ORION_MLMB_NREMAP; 340 341 cs = MARVELL_TAG_SDRAM_CS0; 342 cs_end = MARVELL_TAG_SDRAM_CS3; 343 344 marvell_fixup_mbus(memtag, iotag); 345 break; 346 #endif /* ORION */ 347 348 #ifdef KIRKWOOD 349 case MARVELL_KIRKWOOD_88F6180: 350 case MARVELL_KIRKWOOD_88F6192: 351 case MARVELL_KIRKWOOD_88F6281: 352 case MARVELL_KIRKWOOD_88F6282: 353 cpu_reset_address = marvell_system_reset; 354 355 kirkwood_bootstrap(MARVELL_INTERREGS_VBASE); 356 357 memtag = KIRKWOOD_TAG_PEX_MEM; 358 iotag = KIRKWOOD_TAG_PEX_IO; 359 nwindow = KIRKWOOD_MLMB_NWINDOW; 360 nremap = KIRKWOOD_MLMB_NREMAP; 361 362 cs = MARVELL_TAG_SDRAM_CS0; 363 cs_end = MARVELL_TAG_SDRAM_CS3; 364 365 marvell_fixup_mbus(memtag, iotag); 366 break; 367 #endif /* KIRKWOOD */ 368 369 #ifdef MV78XX0 370 case MARVELL_MV78XX0_MV78100: 371 case MARVELL_MV78XX0_MV78200: 372 cpu_reset_address = marvell_system_reset; 373 374 mv78xx0_bootstrap(MARVELL_INTERREGS_VBASE); 375 376 memtag = MV78XX0_TAG_PEX0_MEM; 377 iotag = MV78XX0_TAG_PEX0_IO; 378 nwindow = MV78XX0_MLMB_NWINDOW; 379 nremap = MV78XX0_MLMB_NREMAP; 380 381 cs = MARVELL_TAG_SDRAM_CS0; 382 cs_end = MARVELL_TAG_SDRAM_CS3; 383 384 marvell_fixup_mbus(memtag, iotag); 385 break; 386 #endif /* MV78XX0 */ 387 388 #ifdef DOVE 389 case MARVELL_DOVE_88AP510: 390 cpu_reset_address = marvell_system_reset; 391 392 dove_bootstrap(MARVELL_INTERREGS_VBASE); 393 394 memtag = DOVE_TAG_PEX0_MEM; 395 iotag = DOVE_TAG_PEX0_IO; 396 nwindow = DOVE_DB_NWINDOW; 397 nremap = DOVE_DB_NREMAP; 398 399 cs = MARVELL_TAG_AXI_CS0; 400 cs_end = MARVELL_TAG_AXI_CS1; 401 402 marvell_fixup_mbus(memtag, iotag); 403 break; 404 #endif /* DOVE */ 405 406 #ifdef ARMADAXP 407 case MARVELL_ARMADAXP_MV78130: 408 case MARVELL_ARMADAXP_MV78160: 409 case MARVELL_ARMADAXP_MV78230: 410 case MARVELL_ARMADAXP_MV78260: 411 case MARVELL_ARMADAXP_MV78460: 412 case MARVELL_ARMADA370_MV6707: 413 case MARVELL_ARMADA370_MV6710: 414 case MARVELL_ARMADA370_MV6W11: 415 cpu_reset_address = armadaxp_system_reset; 416 417 armadaxp_bootstrap( 418 MARVELL_INTERREGS_VBASE, 419 MARVELL_INTERREGS_PBASE); 420 421 memtag = ARMADAXP_TAG_PEX00_MEM; 422 iotag = ARMADAXP_TAG_PEX00_IO; 423 nwindow = ARMADAXP_MLMB_NWINDOW; 424 nremap = ARMADAXP_MLMB_NREMAP; 425 426 cs = MARVELL_TAG_DDR3_CS0; 427 cs_end = MARVELL_TAG_DDR3_CS3; 428 429 armadaxp_fixup_mbus(memtag, iotag); 430 break; 431 #endif /* ARMADAXP */ 432 433 default: 434 /* We can't output console here yet... */ 435 panic("unknown model...\n"); 436 437 /* NOTREACHED */ 438 } 439 440 consinit(); 441 442 /* Talk to the user */ 443 #ifndef EVBARM_BOARDTYPE 444 #define EVBARM_BOARDTYPE Marvell 445 #endif 446 #define BDSTR(s) _BDSTR(s) 447 #define _BDSTR(s) #s 448 printf("\nNetBSD/evbarm (" BDSTR(EVBARM_BOARDTYPE) ") booting ...\n"); 449 450 /* copy command line U-Boot gave us, if args is valid. */ 451 if (u_boot_args[3] != 0) /* XXXXX: need more check?? */ 452 strncpy(bootargs, (char *)u_boot_args[3], sizeof(bootargs)); 453 454 #ifdef VERBOSE_INIT_ARM 455 printf("initarm: Configuring system ...\n"); 456 #endif 457 458 bootconfig.dramblocks = 0; 459 paddr_t segment_end; 460 segment_end = physmem = 0; 461 for ( ; cs <= cs_end; cs++) { 462 uint32_t base, size; 463 464 mvsoc_target(cs, NULL, NULL, &base, &size); 465 if (size == 0) 466 continue; 467 468 bootconfig.dram[bootconfig.dramblocks].address = base; 469 bootconfig.dram[bootconfig.dramblocks].pages = size / PAGE_SIZE; 470 471 if (base != segment_end) 472 panic("memory hole not support"); 473 474 segment_end += size; 475 physmem += size / PAGE_SIZE; 476 477 bootconfig.dramblocks++; 478 } 479 480 #ifdef __HAVE_MM_MD_DIRECT_MAPPED_PHYS 481 const bool mapallmem_p = true; 482 #else 483 const bool mapallmem_p = false; 484 #endif 485 486 arm32_bootmem_init(0, segment_end, (uintptr_t) KERNEL_BASE_phys); 487 arm32_kernel_vm_init(KERNEL_VM_BASE, ARM_VECTORS_HIGH, 0, 488 marvell_devmap, mapallmem_p); 489 490 /* we've a specific device_register routine */ 491 evbarm_device_register = marvell_device_register; 492 493 /* parse bootargs from U-Boot */ 494 boot_args = bootargs; 495 parse_mi_bootargs(boot_args); 496 497 return initarm_common(KERNEL_VM_BASE, KERNEL_VM_SIZE, NULL, 0); 498 } 499 500 void 501 consinit(void) 502 { 503 static int consinit_called = 0; 504 505 if (consinit_called != 0) 506 return; 507 508 consinit_called = 1; 509 510 #if NCOM > 0 511 { 512 extern int mvuart_cnattach(bus_space_tag_t, bus_addr_t, int, 513 uint32_t, int); 514 515 if (mvuart_cnattach(&mvsoc_bs_tag, 516 MARVELL_INTERREGS_PBASE + MVSOC_COM0_BASE, 517 comcnspeed, mvTclk, comcnmode)) 518 panic("can't init serial console"); 519 } 520 #else 521 panic("serial console not configured"); 522 #endif 523 } 524 525 526 static void 527 marvell_device_register(device_t dev, void *aux) 528 { 529 prop_dictionary_t dict = device_properties(dev); 530 531 #if NCOM > 0 532 if (device_is_a(dev, "com") && 533 device_is_a(device_parent(dev), "mvsoc")) 534 prop_dictionary_set_uint32(dict, "frequency", mvTclk); 535 #endif 536 537 if (device_is_a(dev, "gtidmac")) 538 prop_dictionary_set_uint32(dict, 539 "dmb_speed", mvTclk * sizeof(uint32_t)); /* XXXXXX */ 540 541 #if NGTPCI > 0 && defined(ORION) 542 if (device_is_a(dev, "gtpci")) { 543 extern struct bus_space 544 orion_pci_io_bs_tag, orion_pci_mem_bs_tag; 545 extern struct arm32_pci_chipset arm32_gtpci_chipset; 546 547 prop_data_t io_bs_tag, mem_bs_tag, pc; 548 prop_array_t int2gpp; 549 prop_number_t gpp; 550 uint64_t start, end; 551 int i, j; 552 static struct { 553 const char *boardtype; 554 int pin[PCI_INTERRUPT_PIN_MAX]; 555 } hints[] = { 556 { "kuronas_x4", 557 { 11, PCI_INTERRUPT_PIN_NONE } }, 558 559 { NULL, 560 { PCI_INTERRUPT_PIN_NONE } }, 561 }; 562 563 arm32_gtpci_chipset.pc_conf_v = device_private(dev); 564 arm32_gtpci_chipset.pc_intr_v = device_private(dev); 565 566 io_bs_tag = prop_data_create_data_nocopy( 567 &orion_pci_io_bs_tag, sizeof(struct bus_space)); 568 KASSERT(io_bs_tag != NULL); 569 prop_dictionary_set(dict, "io-bus-tag", io_bs_tag); 570 prop_object_release(io_bs_tag); 571 mem_bs_tag = prop_data_create_data_nocopy( 572 &orion_pci_mem_bs_tag, sizeof(struct bus_space)); 573 KASSERT(mem_bs_tag != NULL); 574 prop_dictionary_set(dict, "mem-bus-tag", mem_bs_tag); 575 prop_object_release(mem_bs_tag); 576 577 pc = prop_data_create_data_nocopy(&arm32_gtpci_chipset, 578 sizeof(struct arm32_pci_chipset)); 579 KASSERT(pc != NULL); 580 prop_dictionary_set(dict, "pci-chipset", pc); 581 prop_object_release(pc); 582 583 marvell_startend_by_tag(ORION_TAG_PCI_IO, &start, &end); 584 prop_dictionary_set_uint64(dict, "iostart", start); 585 prop_dictionary_set_uint64(dict, "ioend", end); 586 marvell_startend_by_tag(ORION_TAG_PCI_MEM, &start, &end); 587 prop_dictionary_set_uint64(dict, "memstart", start); 588 prop_dictionary_set_uint64(dict, "memend", end); 589 prop_dictionary_set_uint32(dict, 590 "cache-line-size", arm_dcache_align); 591 592 /* Setup the hint for interrupt-pin. */ 593 #define BDSTR(s) _BDSTR(s) 594 #define _BDSTR(s) #s 595 #define THIS_BOARD(str) (strcmp(str, BDSTR(EVBARM_BOARDTYPE)) == 0) 596 for (i = 0; hints[i].boardtype != NULL; i++) 597 if (THIS_BOARD(hints[i].boardtype)) 598 break; 599 if (hints[i].boardtype == NULL) 600 return; 601 602 int2gpp = 603 prop_array_create_with_capacity(PCI_INTERRUPT_PIN_MAX + 1); 604 605 /* first set dummy */ 606 gpp = prop_number_create_integer(0); 607 prop_array_add(int2gpp, gpp); 608 prop_object_release(gpp); 609 610 for (j = 0; hints[i].pin[j] != PCI_INTERRUPT_PIN_NONE; j++) { 611 gpp = prop_number_create_integer(hints[i].pin[j]); 612 prop_array_add(int2gpp, gpp); 613 prop_object_release(gpp); 614 } 615 prop_dictionary_set(dict, "int2gpp", int2gpp); 616 } 617 #endif /* NGTPCI > 0 && defined(ORION) */ 618 619 #if NMVPEX > 0 620 if (device_is_a(dev, "mvpex")) { 621 #ifdef ORION 622 extern struct bus_space 623 orion_pex0_io_bs_tag, orion_pex0_mem_bs_tag, 624 orion_pex1_io_bs_tag, orion_pex1_mem_bs_tag; 625 #endif 626 #ifdef KIRKWOOD 627 extern struct bus_space 628 kirkwood_pex_io_bs_tag, kirkwood_pex_mem_bs_tag, 629 kirkwood_pex1_io_bs_tag, kirkwood_pex1_mem_bs_tag; 630 #endif 631 #ifdef DOVE 632 extern struct bus_space 633 dove_pex0_io_bs_tag, dove_pex0_mem_bs_tag, 634 dove_pex1_io_bs_tag, dove_pex1_mem_bs_tag; 635 #endif 636 #ifdef ARMADAXP 637 extern struct bus_space 638 armadaxp_pex00_io_bs_tag, armadaxp_pex00_mem_bs_tag, 639 armadaxp_pex01_io_bs_tag, armadaxp_pex01_mem_bs_tag, 640 armadaxp_pex02_io_bs_tag, armadaxp_pex02_mem_bs_tag, 641 armadaxp_pex03_io_bs_tag, armadaxp_pex03_mem_bs_tag, 642 armadaxp_pex2_io_bs_tag, armadaxp_pex2_mem_bs_tag, 643 armadaxp_pex3_io_bs_tag, armadaxp_pex3_mem_bs_tag; 644 int i; 645 #endif 646 extern struct arm32_pci_chipset 647 arm32_mvpex0_chipset, arm32_mvpex1_chipset; 648 649 struct marvell_attach_args *mva = aux; 650 struct bus_space *mvpex_io_bs_tag, *mvpex_mem_bs_tag; 651 struct arm32_pci_chipset *arm32_mvpex_chipset; 652 prop_data_t io_bs_tag, mem_bs_tag, pc; 653 uint64_t start, end; 654 int iotag, memtag; 655 656 switch (mvsoc_model()) { 657 #ifdef ORION 658 case MARVELL_ORION_1_88F5180N: 659 case MARVELL_ORION_1_88F5181: 660 case MARVELL_ORION_1_88F5182: 661 case MARVELL_ORION_1_88W8660: 662 case MARVELL_ORION_2_88F5281: 663 if (mva->mva_offset == MVSOC_PEX_BASE) { 664 mvpex_io_bs_tag = &orion_pex0_io_bs_tag; 665 mvpex_mem_bs_tag = &orion_pex0_mem_bs_tag; 666 arm32_mvpex_chipset = &arm32_mvpex0_chipset; 667 iotag = ORION_TAG_PEX0_IO; 668 memtag = ORION_TAG_PEX0_MEM; 669 } else { 670 mvpex_io_bs_tag = &orion_pex1_io_bs_tag; 671 mvpex_mem_bs_tag = &orion_pex1_mem_bs_tag; 672 arm32_mvpex_chipset = &arm32_mvpex1_chipset; 673 iotag = ORION_TAG_PEX1_IO; 674 memtag = ORION_TAG_PEX1_MEM; 675 } 676 break; 677 #endif 678 679 #ifdef KIRKWOOD 680 case MARVELL_KIRKWOOD_88F6282: 681 if (mva->mva_offset != MVSOC_PEX_BASE) { 682 mvpex_io_bs_tag = &kirkwood_pex1_io_bs_tag; 683 mvpex_mem_bs_tag = &kirkwood_pex1_mem_bs_tag; 684 arm32_mvpex_chipset = &arm32_mvpex1_chipset; 685 iotag = KIRKWOOD_TAG_PEX1_IO; 686 memtag = KIRKWOOD_TAG_PEX1_MEM; 687 break; 688 } 689 690 /* FALLTHROUGH */ 691 692 case MARVELL_KIRKWOOD_88F6180: 693 case MARVELL_KIRKWOOD_88F6192: 694 case MARVELL_KIRKWOOD_88F6281: 695 mvpex_io_bs_tag = &kirkwood_pex_io_bs_tag; 696 mvpex_mem_bs_tag = &kirkwood_pex_mem_bs_tag; 697 arm32_mvpex_chipset = &arm32_mvpex0_chipset; 698 iotag = KIRKWOOD_TAG_PEX_IO; 699 memtag = KIRKWOOD_TAG_PEX_MEM; 700 break; 701 #endif 702 703 #ifdef DOVE 704 case MARVELL_DOVE_88AP510: 705 if (mva->mva_offset == MVSOC_PEX_BASE) { 706 mvpex_io_bs_tag = &dove_pex0_io_bs_tag; 707 mvpex_mem_bs_tag = &dove_pex0_mem_bs_tag; 708 arm32_mvpex_chipset = &arm32_mvpex0_chipset; 709 iotag = DOVE_TAG_PEX0_IO; 710 memtag = DOVE_TAG_PEX0_MEM; 711 } else { 712 mvpex_io_bs_tag = &dove_pex1_io_bs_tag; 713 mvpex_mem_bs_tag = &dove_pex1_mem_bs_tag; 714 arm32_mvpex_chipset = &arm32_mvpex1_chipset; 715 iotag = DOVE_TAG_PEX1_IO; 716 memtag = DOVE_TAG_PEX1_MEM; 717 } 718 break; 719 #endif 720 721 #ifdef ARMADAXP 722 case MARVELL_ARMADAXP_MV78130: 723 case MARVELL_ARMADAXP_MV78160: 724 case MARVELL_ARMADAXP_MV78230: 725 case MARVELL_ARMADAXP_MV78260: 726 case MARVELL_ARMADAXP_MV78460: 727 728 case MARVELL_ARMADA370_MV6707: 729 case MARVELL_ARMADA370_MV6710: 730 case MARVELL_ARMADA370_MV6W11: 731 { 732 extern struct arm32_pci_chipset 733 arm32_mvpex2_chipset, arm32_mvpex3_chipset, 734 arm32_mvpex4_chipset, arm32_mvpex5_chipset; 735 const struct { 736 bus_size_t offset; 737 struct bus_space *io_bs_tag; 738 struct bus_space *mem_bs_tag; 739 struct arm32_pci_chipset *chipset; 740 int iotag; 741 int memtag; 742 } mvpex_tags[] = { 743 { MVSOC_PEX_BASE, 744 &armadaxp_pex00_io_bs_tag, 745 &armadaxp_pex00_mem_bs_tag, 746 &arm32_mvpex0_chipset, 747 ARMADAXP_TAG_PEX00_IO, 748 ARMADAXP_TAG_PEX00_MEM }, 749 750 { ARMADAXP_PEX01_BASE, 751 &armadaxp_pex01_io_bs_tag, 752 &armadaxp_pex01_mem_bs_tag, 753 &arm32_mvpex1_chipset, 754 ARMADAXP_TAG_PEX01_IO, 755 ARMADAXP_TAG_PEX01_MEM }, 756 757 { ARMADAXP_PEX02_BASE, 758 &armadaxp_pex02_io_bs_tag, 759 &armadaxp_pex02_mem_bs_tag, 760 &arm32_mvpex2_chipset, 761 ARMADAXP_TAG_PEX02_IO, 762 ARMADAXP_TAG_PEX02_MEM }, 763 764 { ARMADAXP_PEX03_BASE, 765 &armadaxp_pex03_io_bs_tag, 766 &armadaxp_pex03_mem_bs_tag, 767 &arm32_mvpex3_chipset, 768 ARMADAXP_TAG_PEX03_IO, 769 ARMADAXP_TAG_PEX03_MEM }, 770 771 { ARMADAXP_PEX2_BASE, 772 &armadaxp_pex2_io_bs_tag, 773 &armadaxp_pex2_mem_bs_tag, 774 &arm32_mvpex4_chipset, 775 ARMADAXP_TAG_PEX2_IO, 776 ARMADAXP_TAG_PEX2_MEM }, 777 778 { ARMADAXP_PEX3_BASE, 779 &armadaxp_pex3_io_bs_tag, 780 &armadaxp_pex3_mem_bs_tag, 781 &arm32_mvpex5_chipset, 782 ARMADAXP_TAG_PEX3_IO, 783 ARMADAXP_TAG_PEX3_MEM }, 784 785 { 0, 0, 0, 0, 0 }, 786 }; 787 788 for (i = 0; mvpex_tags[i].offset != 0; i++) { 789 if (mva->mva_offset != mvpex_tags[i].offset) 790 continue; 791 break; 792 } 793 if (mvpex_tags[i].offset == 0) 794 return; 795 mvpex_io_bs_tag = mvpex_tags[i].io_bs_tag; 796 mvpex_mem_bs_tag = mvpex_tags[i].mem_bs_tag; 797 arm32_mvpex_chipset = mvpex_tags[i].chipset; 798 iotag = mvpex_tags[i].iotag; 799 memtag = mvpex_tags[i].memtag; 800 break; 801 } 802 #endif 803 804 default: 805 return; 806 } 807 808 arm32_mvpex_chipset->pc_conf_v = device_private(dev); 809 arm32_mvpex_chipset->pc_intr_v = device_private(dev); 810 811 io_bs_tag = prop_data_create_data_nocopy( 812 mvpex_io_bs_tag, sizeof(struct bus_space)); 813 KASSERT(io_bs_tag != NULL); 814 prop_dictionary_set(dict, "io-bus-tag", io_bs_tag); 815 prop_object_release(io_bs_tag); 816 mem_bs_tag = prop_data_create_data_nocopy( 817 mvpex_mem_bs_tag, sizeof(struct bus_space)); 818 KASSERT(mem_bs_tag != NULL); 819 prop_dictionary_set(dict, "mem-bus-tag", mem_bs_tag); 820 prop_object_release(mem_bs_tag); 821 822 pc = prop_data_create_data_nocopy(arm32_mvpex_chipset, 823 sizeof(struct arm32_pci_chipset)); 824 KASSERT(pc != NULL); 825 prop_dictionary_set(dict, "pci-chipset", pc); 826 prop_object_release(pc); 827 828 marvell_startend_by_tag(iotag, &start, &end); 829 prop_dictionary_set_uint64(dict, "iostart", start); 830 prop_dictionary_set_uint64(dict, "ioend", end); 831 marvell_startend_by_tag(memtag, &start, &end); 832 prop_dictionary_set_uint64(dict, "memstart", start); 833 prop_dictionary_set_uint64(dict, "memend", end); 834 prop_dictionary_set_uint32(dict, 835 "cache-line-size", arm_dcache_align); 836 } 837 #endif 838 } 839 840 #if NGTPCI > 0 || NMVPEX > 0 841 static void 842 marvell_startend_by_tag(int tag, uint64_t *start, uint64_t *end) 843 { 844 uint32_t base, size; 845 int win; 846 847 win = mvsoc_target(tag, NULL, NULL, &base, &size); 848 if (size != 0) { 849 if (win < nremap) 850 *start = read_mlmbreg(MVSOC_MLMB_WRLR(win)) | 851 ((read_mlmbreg(MVSOC_MLMB_WRHR(win)) << 16) << 16); 852 else 853 *start = base; 854 *end = *start + size - 1; 855 } 856 } 857 #endif 858