1 /* $NetBSD: marvell_machdep.c,v 1.38 2023/04/20 08:28:05 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.38 2023/04/20 08:28:05 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) \ 212 (*(volatile uint32_t *)(misc_base + (r)) = htole32(v)) 213 214 /* Unmask soft reset */ 215 write_miscreg(ARMADAXP_MISC_RSTOUTNMASKR, 216 ARMADAXP_MISC_RSTOUTNMASKR_GLOBALSOFTRSTOUTEN); 217 /* Assert soft reset */ 218 write_miscreg(ARMADAXP_MISC_SSRR, ARMADAXP_MISC_SSRR_GLOBALSOFTRST); 219 220 while (1); 221 222 /*NOTREACHED*/ 223 } 224 225 static void 226 armadaxp_fixup_mbus(int memtag, int iotag) 227 { 228 /* force set SoC default parameters */ 229 armadaxp_init_mbus(); 230 231 /* set marvell common PEX params */ 232 marvell_fixup_mbus_pex(memtag, iotag); 233 234 /* other configurations? */ 235 } 236 #endif 237 238 239 static inline pd_entry_t * 240 read_ttb(void) 241 { 242 243 return (pd_entry_t *)(armreg_ttbr_read() & ~((1<<14)-1)); 244 } 245 246 /* 247 * Static device mappings. These peripheral registers are mapped at 248 * fixed virtual addresses very early in initarm() so that we can use 249 * them while booting the kernel, and stay at the same address 250 * throughout whole kernel's life time. 251 * 252 * We use this table twice; once with bootstrap page table, and once 253 * with kernel's page table which we build up in initarm(). 254 * 255 * Since we map these registers into the bootstrap page table using 256 * pmap_devmap_bootstrap() which calls pmap_map_chunk(), we map 257 * registers segment-aligned and segment-rounded in order to avoid 258 * using the 2nd page tables. 259 */ 260 261 static struct pmap_devmap marvell_devmap[] = { 262 DEVMAP_ENTRY( 263 MARVELL_INTERREGS_VBASE, 264 MARVELL_INTERREGS_PBASE, 265 MVSOC_INTERREGS_SIZE 266 ), 267 DEVMAP_ENTRY_END 268 }; 269 270 extern uint32_t *u_boot_args[]; 271 272 /* 273 * vaddr_t initarm(...) 274 * 275 * Initial entry point on startup. This gets called before main() is 276 * entered. 277 * It should be responsible for setting up everything that must be 278 * in place when main is called. 279 * This includes 280 * Taking a copy of the boot configuration structure. 281 * Initialising the physical console so characters can be printed. 282 * Setting up page tables for the kernel 283 * Relocating the kernel to the bottom of physical memory 284 */ 285 vaddr_t 286 initarm(void *arg) 287 { 288 int cs, cs_end, memtag = 0, iotag = 0; 289 290 mvsoc_bootstrap(MARVELL_INTERREGS_VBASE); 291 292 /* 293 * Heads up ... Setup the CPU / MMU / TLB functions 294 */ 295 if (set_cpufuncs()) 296 panic("cpu not recognized!"); 297 298 /* map some peripheral registers */ 299 pmap_devmap_bootstrap((vaddr_t)read_ttb(), marvell_devmap); 300 301 /* 302 * U-Boot doesn't use the virtual memory. 303 * 304 * Physical Address Range Description 305 * ----------------------- ---------------------------------- 306 * 0x00000000 - 0x0fffffff SDRAM Bank 0 (max 256MB) 307 * 0x10000000 - 0x1fffffff SDRAM Bank 1 (max 256MB) 308 * 0x20000000 - 0x2fffffff SDRAM Bank 2 (max 256MB) 309 * 0x30000000 - 0x3fffffff SDRAM Bank 3 (max 256MB) 310 * 0xf1000000 - 0xf10fffff SoC Internal Registers 311 */ 312 313 cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT); 314 315 /* Get ready for splfoo() */ 316 switch (mvsoc_model()) { 317 #ifdef ORION 318 case MARVELL_ORION_1_88F1181: 319 case MARVELL_ORION_1_88F5082: 320 case MARVELL_ORION_1_88F5180N: 321 case MARVELL_ORION_1_88F5181: 322 case MARVELL_ORION_1_88F5182: 323 case MARVELL_ORION_1_88F6082: 324 case MARVELL_ORION_1_88F6183: 325 case MARVELL_ORION_1_88W8660: 326 case MARVELL_ORION_2_88F1281: 327 case MARVELL_ORION_2_88F5281: 328 cpu_reset_address = marvell_system_reset; 329 330 orion_bootstrap(MARVELL_INTERREGS_VBASE); 331 332 memtag = ORION_TAG_PEX0_MEM; 333 iotag = ORION_TAG_PEX0_IO; 334 nwindow = ORION_MLMB_NWINDOW; 335 nremap = ORION_MLMB_NREMAP; 336 337 cs = MARVELL_TAG_SDRAM_CS0; 338 cs_end = MARVELL_TAG_SDRAM_CS3; 339 340 marvell_fixup_mbus(memtag, iotag); 341 break; 342 #endif /* ORION */ 343 344 #ifdef KIRKWOOD 345 case MARVELL_KIRKWOOD_88F6180: 346 case MARVELL_KIRKWOOD_88F6192: 347 case MARVELL_KIRKWOOD_88F6281: 348 case MARVELL_KIRKWOOD_88F6282: 349 cpu_reset_address = marvell_system_reset; 350 351 kirkwood_bootstrap(MARVELL_INTERREGS_VBASE); 352 353 memtag = KIRKWOOD_TAG_PEX_MEM; 354 iotag = KIRKWOOD_TAG_PEX_IO; 355 nwindow = KIRKWOOD_MLMB_NWINDOW; 356 nremap = KIRKWOOD_MLMB_NREMAP; 357 358 cs = MARVELL_TAG_SDRAM_CS0; 359 cs_end = MARVELL_TAG_SDRAM_CS3; 360 361 marvell_fixup_mbus(memtag, iotag); 362 break; 363 #endif /* KIRKWOOD */ 364 365 #ifdef MV78XX0 366 case MARVELL_MV78XX0_MV78100: 367 case MARVELL_MV78XX0_MV78200: 368 cpu_reset_address = marvell_system_reset; 369 370 mv78xx0_bootstrap(MARVELL_INTERREGS_VBASE); 371 372 memtag = MV78XX0_TAG_PEX0_MEM; 373 iotag = MV78XX0_TAG_PEX0_IO; 374 nwindow = MV78XX0_MLMB_NWINDOW; 375 nremap = MV78XX0_MLMB_NREMAP; 376 377 cs = MARVELL_TAG_SDRAM_CS0; 378 cs_end = MARVELL_TAG_SDRAM_CS3; 379 380 marvell_fixup_mbus(memtag, iotag); 381 break; 382 #endif /* MV78XX0 */ 383 384 #ifdef DOVE 385 case MARVELL_DOVE_88AP510: 386 cpu_reset_address = marvell_system_reset; 387 388 dove_bootstrap(MARVELL_INTERREGS_VBASE); 389 390 memtag = DOVE_TAG_PEX0_MEM; 391 iotag = DOVE_TAG_PEX0_IO; 392 nwindow = DOVE_DB_NWINDOW; 393 nremap = DOVE_DB_NREMAP; 394 395 cs = MARVELL_TAG_AXI_CS0; 396 cs_end = MARVELL_TAG_AXI_CS1; 397 398 marvell_fixup_mbus(memtag, iotag); 399 break; 400 #endif /* DOVE */ 401 402 #ifdef ARMADAXP 403 case MARVELL_ARMADAXP_MV78130: 404 case MARVELL_ARMADAXP_MV78160: 405 case MARVELL_ARMADAXP_MV78230: 406 case MARVELL_ARMADAXP_MV78260: 407 case MARVELL_ARMADAXP_MV78460: 408 case MARVELL_ARMADA370_MV6707: 409 case MARVELL_ARMADA370_MV6710: 410 case MARVELL_ARMADA370_MV6W11: 411 cpu_reset_address = armadaxp_system_reset; 412 413 armadaxp_bootstrap( 414 MARVELL_INTERREGS_VBASE, 415 MARVELL_INTERREGS_PBASE); 416 417 memtag = ARMADAXP_TAG_PEX00_MEM; 418 iotag = ARMADAXP_TAG_PEX00_IO; 419 nwindow = ARMADAXP_MLMB_NWINDOW; 420 nremap = ARMADAXP_MLMB_NREMAP; 421 422 cs = MARVELL_TAG_DDR3_CS0; 423 cs_end = MARVELL_TAG_DDR3_CS3; 424 425 armadaxp_fixup_mbus(memtag, iotag); 426 break; 427 #endif /* ARMADAXP */ 428 429 default: 430 /* We can't output console here yet... */ 431 panic("unknown model...\n"); 432 433 /* NOTREACHED */ 434 } 435 436 consinit(); 437 438 /* Talk to the user */ 439 #ifndef EVBARM_BOARDTYPE 440 #define EVBARM_BOARDTYPE Marvell 441 #endif 442 #define BDSTR(s) _BDSTR(s) 443 #define _BDSTR(s) #s 444 printf("\nNetBSD/evbarm (" BDSTR(EVBARM_BOARDTYPE) ") booting ...\n"); 445 446 /* copy command line U-Boot gave us, if args is valid. */ 447 if (u_boot_args[3] != 0) /* XXXXX: need more check?? */ 448 strncpy(bootargs, (char *)u_boot_args[3], sizeof(bootargs)); 449 450 #ifdef VERBOSE_INIT_ARM 451 printf("initarm: Configuring system ...\n"); 452 #endif 453 454 bootconfig.dramblocks = 0; 455 paddr_t segment_end; 456 segment_end = physmem = 0; 457 for ( ; cs <= cs_end; cs++) { 458 uint32_t base, size; 459 460 mvsoc_target(cs, NULL, NULL, &base, &size); 461 if (size == 0) 462 continue; 463 464 bootconfig.dram[bootconfig.dramblocks].address = base; 465 bootconfig.dram[bootconfig.dramblocks].pages = size / PAGE_SIZE; 466 467 if (base != segment_end) 468 panic("memory hole not support"); 469 470 segment_end += size; 471 physmem += size / PAGE_SIZE; 472 473 bootconfig.dramblocks++; 474 } 475 476 #ifdef __HAVE_MM_MD_DIRECT_MAPPED_PHYS 477 const bool mapallmem_p = true; 478 #else 479 const bool mapallmem_p = false; 480 #endif 481 482 arm32_bootmem_init(0, segment_end, (uintptr_t) KERNEL_BASE_phys); 483 arm32_kernel_vm_init(KERNEL_VM_BASE, ARM_VECTORS_HIGH, 0, 484 marvell_devmap, mapallmem_p); 485 486 /* we've a specific device_register routine */ 487 evbarm_device_register = marvell_device_register; 488 489 /* parse bootargs from U-Boot */ 490 boot_args = bootargs; 491 parse_mi_bootargs(boot_args); 492 493 return initarm_common(KERNEL_VM_BASE, KERNEL_VM_SIZE, NULL, 0); 494 } 495 496 void 497 consinit(void) 498 { 499 static int consinit_called = 0; 500 501 if (consinit_called != 0) 502 return; 503 504 consinit_called = 1; 505 506 #if NCOM > 0 507 { 508 extern int mvuart_cnattach(bus_space_tag_t, bus_addr_t, int, 509 uint32_t, int); 510 511 if (mvuart_cnattach(&mvsoc_bs_tag, 512 MARVELL_INTERREGS_PBASE + MVSOC_COM0_BASE, 513 comcnspeed, mvTclk, comcnmode)) 514 panic("can't init serial console"); 515 } 516 #else 517 panic("serial console not configured"); 518 #endif 519 } 520 521 522 static void 523 marvell_device_register(device_t dev, void *aux) 524 { 525 prop_dictionary_t dict = device_properties(dev); 526 527 #if NCOM > 0 528 if (device_is_a(dev, "com") && 529 device_is_a(device_parent(dev), "mvsoc")) 530 prop_dictionary_set_uint32(dict, "frequency", mvTclk); 531 #endif 532 533 if (device_is_a(dev, "gtidmac")) 534 prop_dictionary_set_uint32(dict, 535 "dmb_speed", mvTclk * sizeof(uint32_t)); /* XXXXXX */ 536 537 #if NGTPCI > 0 && defined(ORION) 538 if (device_is_a(dev, "gtpci")) { 539 extern struct bus_space 540 orion_pci_io_bs_tag, orion_pci_mem_bs_tag; 541 extern struct arm32_pci_chipset arm32_gtpci_chipset; 542 543 prop_data_t io_bs_tag, mem_bs_tag, pc; 544 prop_array_t int2gpp; 545 prop_number_t gpp; 546 uint64_t start, end; 547 int i, j; 548 static struct { 549 const char *boardtype; 550 int pin[PCI_INTERRUPT_PIN_MAX]; 551 } hints[] = { 552 { "kuronas_x4", 553 { 11, PCI_INTERRUPT_PIN_NONE } }, 554 555 { NULL, 556 { PCI_INTERRUPT_PIN_NONE } }, 557 }; 558 559 arm32_gtpci_chipset.pc_conf_v = device_private(dev); 560 arm32_gtpci_chipset.pc_intr_v = device_private(dev); 561 562 io_bs_tag = prop_data_create_data_nocopy( 563 &orion_pci_io_bs_tag, sizeof(struct bus_space)); 564 KASSERT(io_bs_tag != NULL); 565 prop_dictionary_set(dict, "io-bus-tag", io_bs_tag); 566 prop_object_release(io_bs_tag); 567 mem_bs_tag = prop_data_create_data_nocopy( 568 &orion_pci_mem_bs_tag, sizeof(struct bus_space)); 569 KASSERT(mem_bs_tag != NULL); 570 prop_dictionary_set(dict, "mem-bus-tag", mem_bs_tag); 571 prop_object_release(mem_bs_tag); 572 573 pc = prop_data_create_data_nocopy(&arm32_gtpci_chipset, 574 sizeof(struct arm32_pci_chipset)); 575 KASSERT(pc != NULL); 576 prop_dictionary_set(dict, "pci-chipset", pc); 577 prop_object_release(pc); 578 579 marvell_startend_by_tag(ORION_TAG_PCI_IO, &start, &end); 580 prop_dictionary_set_uint64(dict, "iostart", start); 581 prop_dictionary_set_uint64(dict, "ioend", end); 582 marvell_startend_by_tag(ORION_TAG_PCI_MEM, &start, &end); 583 prop_dictionary_set_uint64(dict, "memstart", start); 584 prop_dictionary_set_uint64(dict, "memend", end); 585 prop_dictionary_set_uint32(dict, 586 "cache-line-size", arm_dcache_align); 587 588 /* Setup the hint for interrupt-pin. */ 589 #define BDSTR(s) _BDSTR(s) 590 #define _BDSTR(s) #s 591 #define THIS_BOARD(str) (strcmp(str, BDSTR(EVBARM_BOARDTYPE)) == 0) 592 for (i = 0; hints[i].boardtype != NULL; i++) 593 if (THIS_BOARD(hints[i].boardtype)) 594 break; 595 if (hints[i].boardtype == NULL) 596 return; 597 598 int2gpp = 599 prop_array_create_with_capacity(PCI_INTERRUPT_PIN_MAX + 1); 600 601 /* first set dummy */ 602 gpp = prop_number_create_integer(0); 603 prop_array_add(int2gpp, gpp); 604 prop_object_release(gpp); 605 606 for (j = 0; hints[i].pin[j] != PCI_INTERRUPT_PIN_NONE; j++) { 607 gpp = prop_number_create_integer(hints[i].pin[j]); 608 prop_array_add(int2gpp, gpp); 609 prop_object_release(gpp); 610 } 611 prop_dictionary_set(dict, "int2gpp", int2gpp); 612 } 613 #endif /* NGTPCI > 0 && defined(ORION) */ 614 615 #if NMVPEX > 0 616 if (device_is_a(dev, "mvpex")) { 617 #ifdef ORION 618 extern struct bus_space 619 orion_pex0_io_bs_tag, orion_pex0_mem_bs_tag, 620 orion_pex1_io_bs_tag, orion_pex1_mem_bs_tag; 621 #endif 622 #ifdef KIRKWOOD 623 extern struct bus_space 624 kirkwood_pex_io_bs_tag, kirkwood_pex_mem_bs_tag, 625 kirkwood_pex1_io_bs_tag, kirkwood_pex1_mem_bs_tag; 626 #endif 627 #ifdef DOVE 628 extern struct bus_space 629 dove_pex0_io_bs_tag, dove_pex0_mem_bs_tag, 630 dove_pex1_io_bs_tag, dove_pex1_mem_bs_tag; 631 #endif 632 #ifdef ARMADAXP 633 extern struct bus_space 634 armadaxp_pex00_io_bs_tag, armadaxp_pex00_mem_bs_tag, 635 armadaxp_pex01_io_bs_tag, armadaxp_pex01_mem_bs_tag, 636 armadaxp_pex02_io_bs_tag, armadaxp_pex02_mem_bs_tag, 637 armadaxp_pex03_io_bs_tag, armadaxp_pex03_mem_bs_tag, 638 armadaxp_pex2_io_bs_tag, armadaxp_pex2_mem_bs_tag, 639 armadaxp_pex3_io_bs_tag, armadaxp_pex3_mem_bs_tag; 640 int i; 641 #endif 642 extern struct arm32_pci_chipset 643 arm32_mvpex0_chipset, arm32_mvpex1_chipset; 644 645 struct marvell_attach_args *mva = aux; 646 struct bus_space *mvpex_io_bs_tag, *mvpex_mem_bs_tag; 647 struct arm32_pci_chipset *arm32_mvpex_chipset; 648 prop_data_t io_bs_tag, mem_bs_tag, pc; 649 uint64_t start, end; 650 int iotag, memtag; 651 652 switch (mvsoc_model()) { 653 #ifdef ORION 654 case MARVELL_ORION_1_88F5180N: 655 case MARVELL_ORION_1_88F5181: 656 case MARVELL_ORION_1_88F5182: 657 case MARVELL_ORION_1_88W8660: 658 case MARVELL_ORION_2_88F5281: 659 if (mva->mva_offset == MVSOC_PEX_BASE) { 660 mvpex_io_bs_tag = &orion_pex0_io_bs_tag; 661 mvpex_mem_bs_tag = &orion_pex0_mem_bs_tag; 662 arm32_mvpex_chipset = &arm32_mvpex0_chipset; 663 iotag = ORION_TAG_PEX0_IO; 664 memtag = ORION_TAG_PEX0_MEM; 665 } else { 666 mvpex_io_bs_tag = &orion_pex1_io_bs_tag; 667 mvpex_mem_bs_tag = &orion_pex1_mem_bs_tag; 668 arm32_mvpex_chipset = &arm32_mvpex1_chipset; 669 iotag = ORION_TAG_PEX1_IO; 670 memtag = ORION_TAG_PEX1_MEM; 671 } 672 break; 673 #endif 674 675 #ifdef KIRKWOOD 676 case MARVELL_KIRKWOOD_88F6282: 677 if (mva->mva_offset != MVSOC_PEX_BASE) { 678 mvpex_io_bs_tag = &kirkwood_pex1_io_bs_tag; 679 mvpex_mem_bs_tag = &kirkwood_pex1_mem_bs_tag; 680 arm32_mvpex_chipset = &arm32_mvpex1_chipset; 681 iotag = KIRKWOOD_TAG_PEX1_IO; 682 memtag = KIRKWOOD_TAG_PEX1_MEM; 683 break; 684 } 685 686 /* FALLTHROUGH */ 687 688 case MARVELL_KIRKWOOD_88F6180: 689 case MARVELL_KIRKWOOD_88F6192: 690 case MARVELL_KIRKWOOD_88F6281: 691 mvpex_io_bs_tag = &kirkwood_pex_io_bs_tag; 692 mvpex_mem_bs_tag = &kirkwood_pex_mem_bs_tag; 693 arm32_mvpex_chipset = &arm32_mvpex0_chipset; 694 iotag = KIRKWOOD_TAG_PEX_IO; 695 memtag = KIRKWOOD_TAG_PEX_MEM; 696 break; 697 #endif 698 699 #ifdef DOVE 700 case MARVELL_DOVE_88AP510: 701 if (mva->mva_offset == MVSOC_PEX_BASE) { 702 mvpex_io_bs_tag = &dove_pex0_io_bs_tag; 703 mvpex_mem_bs_tag = &dove_pex0_mem_bs_tag; 704 arm32_mvpex_chipset = &arm32_mvpex0_chipset; 705 iotag = DOVE_TAG_PEX0_IO; 706 memtag = DOVE_TAG_PEX0_MEM; 707 } else { 708 mvpex_io_bs_tag = &dove_pex1_io_bs_tag; 709 mvpex_mem_bs_tag = &dove_pex1_mem_bs_tag; 710 arm32_mvpex_chipset = &arm32_mvpex1_chipset; 711 iotag = DOVE_TAG_PEX1_IO; 712 memtag = DOVE_TAG_PEX1_MEM; 713 } 714 break; 715 #endif 716 717 #ifdef ARMADAXP 718 case MARVELL_ARMADAXP_MV78130: 719 case MARVELL_ARMADAXP_MV78160: 720 case MARVELL_ARMADAXP_MV78230: 721 case MARVELL_ARMADAXP_MV78260: 722 case MARVELL_ARMADAXP_MV78460: 723 724 case MARVELL_ARMADA370_MV6707: 725 case MARVELL_ARMADA370_MV6710: 726 case MARVELL_ARMADA370_MV6W11: 727 { 728 extern struct arm32_pci_chipset 729 arm32_mvpex2_chipset, arm32_mvpex3_chipset, 730 arm32_mvpex4_chipset, arm32_mvpex5_chipset; 731 const struct { 732 bus_size_t offset; 733 struct bus_space *io_bs_tag; 734 struct bus_space *mem_bs_tag; 735 struct arm32_pci_chipset *chipset; 736 int iotag; 737 int memtag; 738 } mvpex_tags[] = { 739 { MVSOC_PEX_BASE, 740 &armadaxp_pex00_io_bs_tag, 741 &armadaxp_pex00_mem_bs_tag, 742 &arm32_mvpex0_chipset, 743 ARMADAXP_TAG_PEX00_IO, 744 ARMADAXP_TAG_PEX00_MEM }, 745 746 { ARMADAXP_PEX01_BASE, 747 &armadaxp_pex01_io_bs_tag, 748 &armadaxp_pex01_mem_bs_tag, 749 &arm32_mvpex1_chipset, 750 ARMADAXP_TAG_PEX01_IO, 751 ARMADAXP_TAG_PEX01_MEM }, 752 753 { ARMADAXP_PEX02_BASE, 754 &armadaxp_pex02_io_bs_tag, 755 &armadaxp_pex02_mem_bs_tag, 756 &arm32_mvpex2_chipset, 757 ARMADAXP_TAG_PEX02_IO, 758 ARMADAXP_TAG_PEX02_MEM }, 759 760 { ARMADAXP_PEX03_BASE, 761 &armadaxp_pex03_io_bs_tag, 762 &armadaxp_pex03_mem_bs_tag, 763 &arm32_mvpex3_chipset, 764 ARMADAXP_TAG_PEX03_IO, 765 ARMADAXP_TAG_PEX03_MEM }, 766 767 { ARMADAXP_PEX2_BASE, 768 &armadaxp_pex2_io_bs_tag, 769 &armadaxp_pex2_mem_bs_tag, 770 &arm32_mvpex4_chipset, 771 ARMADAXP_TAG_PEX2_IO, 772 ARMADAXP_TAG_PEX2_MEM }, 773 774 { ARMADAXP_PEX3_BASE, 775 &armadaxp_pex3_io_bs_tag, 776 &armadaxp_pex3_mem_bs_tag, 777 &arm32_mvpex5_chipset, 778 ARMADAXP_TAG_PEX3_IO, 779 ARMADAXP_TAG_PEX3_MEM }, 780 781 { 0, 0, 0, 0, 0 }, 782 }; 783 784 for (i = 0; mvpex_tags[i].offset != 0; i++) { 785 if (mva->mva_offset != mvpex_tags[i].offset) 786 continue; 787 break; 788 } 789 if (mvpex_tags[i].offset == 0) 790 return; 791 mvpex_io_bs_tag = mvpex_tags[i].io_bs_tag; 792 mvpex_mem_bs_tag = mvpex_tags[i].mem_bs_tag; 793 arm32_mvpex_chipset = mvpex_tags[i].chipset; 794 iotag = mvpex_tags[i].iotag; 795 memtag = mvpex_tags[i].memtag; 796 break; 797 } 798 #endif 799 800 default: 801 return; 802 } 803 804 arm32_mvpex_chipset->pc_conf_v = device_private(dev); 805 arm32_mvpex_chipset->pc_intr_v = device_private(dev); 806 807 io_bs_tag = prop_data_create_data_nocopy( 808 mvpex_io_bs_tag, sizeof(struct bus_space)); 809 KASSERT(io_bs_tag != NULL); 810 prop_dictionary_set(dict, "io-bus-tag", io_bs_tag); 811 prop_object_release(io_bs_tag); 812 mem_bs_tag = prop_data_create_data_nocopy( 813 mvpex_mem_bs_tag, sizeof(struct bus_space)); 814 KASSERT(mem_bs_tag != NULL); 815 prop_dictionary_set(dict, "mem-bus-tag", mem_bs_tag); 816 prop_object_release(mem_bs_tag); 817 818 pc = prop_data_create_data_nocopy(arm32_mvpex_chipset, 819 sizeof(struct arm32_pci_chipset)); 820 KASSERT(pc != NULL); 821 prop_dictionary_set(dict, "pci-chipset", pc); 822 prop_object_release(pc); 823 824 marvell_startend_by_tag(iotag, &start, &end); 825 prop_dictionary_set_uint64(dict, "iostart", start); 826 prop_dictionary_set_uint64(dict, "ioend", end); 827 marvell_startend_by_tag(memtag, &start, &end); 828 prop_dictionary_set_uint64(dict, "memstart", start); 829 prop_dictionary_set_uint64(dict, "memend", end); 830 prop_dictionary_set_uint32(dict, 831 "cache-line-size", arm_dcache_align); 832 } 833 #endif 834 } 835 836 #if NGTPCI > 0 || NMVPEX > 0 837 static void 838 marvell_startend_by_tag(int tag, uint64_t *start, uint64_t *end) 839 { 840 uint32_t base, size; 841 int win; 842 843 win = mvsoc_target(tag, NULL, NULL, &base, &size); 844 if (size != 0) { 845 if (win < nremap) 846 *start = read_mlmbreg(MVSOC_MLMB_WRLR(win)) | 847 ((read_mlmbreg(MVSOC_MLMB_WRHR(win)) << 16) << 16); 848 else 849 *start = base; 850 *end = *start + size - 1; 851 } 852 } 853 #endif 854