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