Home | History | Annotate | Line # | Download | only in armadaxp
armadaxp_machdep.c revision 1.7
      1 /*	$NetBSD: armadaxp_machdep.c,v 1.7 2014/03/18 06:17:55 matt Exp $	*/
      2 /*******************************************************************************
      3 Copyright (C) Marvell International Ltd. and its affiliates
      4 
      5 Developed by Semihalf
      6 
      7 ********************************************************************************
      8 Marvell BSD License
      9 
     10 If you received this File from Marvell, you may opt to use, redistribute and/or
     11 modify this File under the following licensing terms.
     12 Redistribution and use in source and binary forms, with or without modification,
     13 are permitted provided that the following conditions are met:
     14 
     15     *   Redistributions of source code must retain the above copyright notice,
     16             this list of conditions and the following disclaimer.
     17 
     18     *   Redistributions in binary form must reproduce the above copyright
     19         notice, this list of conditions and the following disclaimer in the
     20         documentation and/or other materials provided with the distribution.
     21 
     22     *   Neither the name of Marvell nor the names of its contributors may be
     23         used to endorse or promote products derived from this software without
     24         specific prior written permission.
     25 
     26 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
     27 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     28 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     29 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
     30 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     31 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     32 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
     33 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     34 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     35 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     36 
     37 *******************************************************************************/
     38 
     39 #include <sys/cdefs.h>
     40 __KERNEL_RCSID(0, "$NetBSD: armadaxp_machdep.c,v 1.7 2014/03/18 06:17:55 matt Exp $");
     41 
     42 #include "opt_machdep.h"
     43 #include "opt_mvsoc.h"
     44 #include "opt_evbarm_boardtype.h"
     45 #include "opt_com.h"
     46 #include "opt_ddb.h"
     47 #include "opt_kgdb.h"
     48 #include "opt_pci.h"
     49 #include "opt_ipkdb.h"
     50 
     51 #include <sys/bus.h>
     52 #include <sys/param.h>
     53 #include <sys/device.h>
     54 #include <sys/systm.h>
     55 #include <sys/kernel.h>
     56 #include <sys/exec.h>
     57 #include <sys/proc.h>
     58 #include <sys/msgbuf.h>
     59 #include <sys/reboot.h>
     60 #include <sys/termios.h>
     61 #include <sys/ksyms.h>
     62 
     63 #include <uvm/uvm_extern.h>
     64 
     65 #include <sys/conf.h>
     66 #include <dev/cons.h>
     67 #include <dev/md.h>
     68 
     69 #include <dev/pci/pcireg.h>
     70 #include <dev/pci/pcivar.h>
     71 #include <machine/pci_machdep.h>
     72 
     73 #include <machine/db_machdep.h>
     74 #include <ddb/db_sym.h>
     75 #include <ddb/db_extern.h>
     76 #ifdef KGDB
     77 #include <sys/kgdb.h>
     78 #endif
     79 
     80 #include <machine/bootconfig.h>
     81 #include <machine/autoconf.h>
     82 #include <machine/cpu.h>
     83 #include <machine/frame.h>
     84 #include <arm/armreg.h>
     85 #include <arm/undefined.h>
     86 
     87 #include <arm/arm32/machdep.h>
     88 
     89 #include <arm/marvell/mvsocreg.h>
     90 #include <arm/marvell/mvsocvar.h>
     91 #include <arm/marvell/armadaxpreg.h>
     92 
     93 #include <evbarm/marvell/marvellreg.h>
     94 #include <evbarm/marvell/marvellvar.h>
     95 
     96 #include "mvpex.h"
     97 #include "com.h"
     98 #if NCOM > 0
     99 #include <dev/ic/comreg.h>
    100 #include <dev/ic/comvar.h>
    101 #endif
    102 
    103 /*
    104  * Address to call from cpu_reset() to reset the machine.
    105  * This is machine architecture dependent as it varies depending
    106  * on where the ROM appears when you turn the MMU off.
    107  */
    108 
    109 
    110 /* Define various stack sizes in pages */
    111 #define IRQ_STACK_SIZE	1
    112 #define ABT_STACK_SIZE	1
    113 #ifdef IPKDB
    114 #define UND_STACK_SIZE	2
    115 #else
    116 #define UND_STACK_SIZE	1
    117 #endif
    118 
    119 BootConfig bootconfig;		/* Boot config storage */
    120 char *boot_args = NULL;
    121 char *boot_file = NULL;
    122 
    123 extern int KERNEL_BASE_phys[];
    124 
    125 /*extern char KERNEL_BASE_phys[];*/
    126 extern char etext[], __data_start[], _edata[], __bss_start[], __bss_end__[];
    127 extern char _end[];
    128 
    129 /*
    130  * Put some bogus settings of the MEMSTART and MEMSIZE
    131  * if they are not defined in kernel configuration file.
    132  */
    133 #ifndef MEMSTART
    134 #define MEMSTART 0x00000000UL
    135 #endif
    136 #ifndef MEMSIZE
    137 #define MEMSIZE 0x40000000UL
    138 #endif
    139 
    140 #ifndef STARTUP_PAGETABLE_ADDR
    141 #define	STARTUP_PAGETABLE_ADDR 0x00000000UL
    142 #endif
    143 
    144 /* Physical offset of the kernel from MEMSTART */
    145 #define KERNEL_OFFSET		(paddr_t)&KERNEL_BASE_phys
    146 /* Kernel base virtual address */
    147 #define	KERNEL_TEXT_BASE	(KERNEL_BASE + KERNEL_OFFSET)
    148 
    149 #define	KERNEL_VM_BASE		(KERNEL_BASE + 0x01000000)
    150 #define KERNEL_VM_SIZE		0x10000000
    151 
    152 /* Prototypes */
    153 extern int armadaxp_l2_init(bus_addr_t);
    154 extern void armadaxp_io_coherency_init(void);
    155 
    156 void consinit(void);
    157 #ifdef KGDB
    158 static void kgdb_port_init(void);
    159 #endif
    160 
    161 static void axp_device_register(device_t dev, void *aux);
    162 
    163 static void
    164 axp_system_reset(void)
    165 {
    166 	extern vaddr_t misc_base;
    167 
    168 #define write_miscreg(r, v)	(*(volatile uint32_t *)(misc_base + (r)) = (v))
    169 
    170 	cpu_reset_address = 0;
    171 
    172 	/* Unmask soft reset */
    173 	write_miscreg(ARMADAXP_MISC_RSTOUTNMASKR,
    174 	    ARMADAXP_MISC_RSTOUTNMASKR_GLOBALSOFTRSTOUTEN);
    175 	/* Assert soft reset */
    176 	write_miscreg(ARMADAXP_MISC_SSRR, ARMADAXP_MISC_SSRR_GLOBALSOFTRST);
    177 
    178 	while (1);
    179 }
    180 
    181 /*
    182  * Static device mappings. These peripheral registers are mapped at
    183  * fixed virtual addresses very early in initarm() so that we can use
    184  * them while booting the kernel, and stay at the same address
    185  * throughout whole kernel's life time.
    186  *
    187  * We use this table twice; once with bootstrap page table, and once
    188  * with kernel's page table which we build up in initarm().
    189  *
    190  * Since we map these registers into the bootstrap page table using
    191  * pmap_devmap_bootstrap() which calls pmap_map_chunk(), we map
    192  * registers segment-aligned and segment-rounded in order to avoid
    193  * using the 2nd page tables.
    194  */
    195 
    196 #define	_A(a)	((a) & ~L1_S_OFFSET)
    197 #define	_S(s)	(((s) + L1_S_SIZE - 1) & ~(L1_S_SIZE-1))
    198 
    199 static const struct pmap_devmap devmap[] = {
    200 	{
    201 		/* Internal registers */
    202 		.pd_va = _A(MARVELL_INTERREGS_VBASE),
    203 		.pd_pa = _A(MARVELL_INTERREGS_PBASE),
    204 		.pd_size = _S(MARVELL_INTERREGS_SIZE),
    205 		.pd_prot = VM_PROT_READ|VM_PROT_WRITE,
    206 		.pd_cache = PTE_NOCACHE
    207 	},
    208 	{0, 0, 0, 0, 0}
    209 };
    210 
    211 #undef	_A
    212 #undef	_S
    213 
    214 static inline
    215 pd_entry_t *
    216 read_ttb(void)
    217 {
    218 	long ttb;
    219 
    220 	__asm volatile("mrc	p15, 0, %0, c2, c0, 0" : "=r" (ttb));
    221 
    222 	return (pd_entry_t *)(ttb & ~((1<<14)-1));
    223 }
    224 
    225 static int
    226 axp_pcie_free_win(void)
    227 {
    228 	int i;
    229 	/* Find first disabled window */
    230 	for (i = 0; i < ARMADAXP_MLMB_NWINDOW; i++) {
    231 		if ((read_mlmbreg(MVSOC_MLMB_WCR(i)) &
    232 		    MVSOC_MLMB_WCR_WINEN) == 0) {
    233 			return i;
    234 		}
    235 	}
    236 	/* If there is no free window, return erroneous value */
    237 	return (-1);
    238 }
    239 
    240 static void
    241 reset_axp_pcie_win(void)
    242 {
    243 	uint32_t target, attr;
    244 	int memtag = 0, iotag = 0, window, i;
    245 	uint32_t membase;
    246 	uint32_t iobase;
    247 	uint32_t tags[] = { ARMADAXP_TAG_PEX00_MEM, ARMADAXP_TAG_PEX00_IO,
    248 			    ARMADAXP_TAG_PEX01_MEM, ARMADAXP_TAG_PEX01_IO,
    249 			    ARMADAXP_TAG_PEX02_MEM, ARMADAXP_TAG_PEX02_IO,
    250 			    ARMADAXP_TAG_PEX03_MEM, ARMADAXP_TAG_PEX03_IO,
    251 			    ARMADAXP_TAG_PEX2_MEM, ARMADAXP_TAG_PEX2_IO,
    252 			    ARMADAXP_TAG_PEX3_MEM, ARMADAXP_TAG_PEX3_IO};
    253 
    254 	nwindow = ARMADAXP_MLMB_NWINDOW;
    255 	nremap = ARMADAXP_MLMB_NREMAP;
    256 	membase = MARVELL_PEXMEM_PBASE;
    257 	iobase = MARVELL_PEXIO_PBASE;
    258 	for (i = 0; i < __arraycount(tags) / 2; i++) {
    259 		memtag = tags[2 * i];
    260 		iotag = tags[(2 * i) + 1];
    261 
    262 		/* Reset PCI-Express space to window register. */
    263 		window = mvsoc_target(memtag, &target, &attr, NULL, NULL);
    264 
    265 		/* Find free window if we've got spurious one */
    266 		if (window >= nwindow) {
    267 			window = axp_pcie_free_win();
    268 			/* Just break if there is no free windows left */
    269 			if (window < 0) {
    270 				aprint_error(": no free windows for PEX MEM\n");
    271 				break;
    272 			}
    273 		}
    274 		write_mlmbreg(MVSOC_MLMB_WCR(window),
    275 		    MVSOC_MLMB_WCR_WINEN |
    276 		    MVSOC_MLMB_WCR_TARGET(target) |
    277 		    MVSOC_MLMB_WCR_ATTR(attr) |
    278 		    MVSOC_MLMB_WCR_SIZE(MARVELL_PEXMEM_SIZE));
    279 		write_mlmbreg(MVSOC_MLMB_WBR(window),
    280 		    membase & MVSOC_MLMB_WBR_BASE_MASK);
    281 #ifdef PCI_NETBSD_CONFIGURE
    282 		if (window < nremap) {
    283 			write_mlmbreg(MVSOC_MLMB_WRLR(window),
    284 			    membase & MVSOC_MLMB_WRLR_REMAP_MASK);
    285 			write_mlmbreg(MVSOC_MLMB_WRHR(window), 0);
    286 		}
    287 #endif
    288 		window = mvsoc_target(iotag, &target, &attr, NULL, NULL);
    289 
    290 		/* Find free window if we've got spurious one */
    291 		if (window >= nwindow) {
    292 			window = axp_pcie_free_win();
    293 			/* Just break if there is no free windows left */
    294 			if (window < 0) {
    295 				aprint_error(": no free windows for PEX I/O\n");
    296 				break;
    297 			}
    298 		}
    299 		write_mlmbreg(MVSOC_MLMB_WCR(window),
    300 		    MVSOC_MLMB_WCR_WINEN |
    301 		    MVSOC_MLMB_WCR_TARGET(target) |
    302 		    MVSOC_MLMB_WCR_ATTR(attr) |
    303 		    MVSOC_MLMB_WCR_SIZE(MARVELL_PEXIO_SIZE));
    304 		write_mlmbreg(MVSOC_MLMB_WBR(window),
    305 		    iobase & MVSOC_MLMB_WBR_BASE_MASK);
    306 #ifdef PCI_NETBSD_CONFIGURE
    307 		if (window < nremap) {
    308 			write_mlmbreg(MVSOC_MLMB_WRLR(window),
    309 			    iobase & MVSOC_MLMB_WRLR_REMAP_MASK);
    310 			write_mlmbreg(MVSOC_MLMB_WRHR(window), 0);
    311 		}
    312 #endif
    313 		membase += MARVELL_PEXMEM_SIZE;
    314 		iobase += MARVELL_PEXIO_SIZE;
    315 	}
    316 }
    317 
    318 /*
    319  * u_int initarm(...)
    320  *
    321  * Initial entry point on startup. This gets called before main() is
    322  * entered.
    323  * It should be responsible for setting up everything that must be
    324  * in place when main is called.
    325  * This includes
    326  *   Taking a copy of the boot configuration structure.
    327  *   Initialising the physical console so characters can be printed.
    328  *   Setting up page tables for the kernel
    329  *   Relocating the kernel to the bottom of physical memory
    330  */
    331 u_int
    332 initarm(void *arg)
    333 {
    334 	cpu_reset_address = axp_system_reset;
    335 
    336 	mvsoc_bootstrap(MARVELL_INTERREGS_VBASE);
    337 
    338 	/* Set CPU functions */
    339 	if (set_cpufuncs())
    340 		panic("cpu not recognized!");
    341 
    342 	/*
    343 	 * Map devices into the initial page table
    344 	 * in order to use early console during initialization process.
    345 	 * consinit is going to use this mapping.
    346 	 */
    347 	pmap_devmap_bootstrap((vaddr_t)read_ttb(), devmap);
    348 
    349 	/* Initialize system console */
    350 	consinit();
    351 
    352 	/* Reset PCI-Express space to window register. */
    353 	reset_axp_pcie_win();
    354 
    355 	/* Get CPU, system and timebase frequencies */
    356 	extern vaddr_t misc_base;
    357 	misc_base = MARVELL_INTERREGS_VBASE + ARMADAXP_MISC_BASE;
    358 	armadaxp_getclks();
    359 	mvsoc_clkgating = armadaxp_clkgating;
    360 
    361 	/* Preconfigure interrupts */
    362 	armadaxp_intr_bootstrap(MARVELL_INTERREGS_PBASE);
    363 
    364 #ifdef L2CACHE_ENABLE
    365 	/* Initialize L2 Cache */
    366 	(void)armadaxp_l2_init(MARVELL_INTERREGS_PBASE);
    367 #endif
    368 
    369 #ifdef AURORA_IO_CACHE_COHERENCY
    370 	/* Initialize cache coherency */
    371 	armadaxp_io_coherency_init();
    372 #endif
    373 
    374 #ifdef KGDB
    375 	kgdb_port_init();
    376 #endif
    377 
    378 #ifdef VERBOSE_INIT_ARM
    379 	/* Talk to the user */
    380 #define	BDSTR(s)	_BDSTR(s)
    381 #define	_BDSTR(s)	#s
    382 	printf("\nNetBSD/evbarm (" BDSTR(EVBARM_BOARDTYPE) ") booting ...\n");
    383 #endif
    384 
    385 
    386 #ifdef VERBOSE_INIT_ARM
    387 	printf("initarm: Configuring system ...\n");
    388 #endif
    389 	/* Fake bootconfig structure for the benefit of pmap.c. */
    390 	bootconfig.dramblocks = 1;
    391 	bootconfig.dram[0].address = MEMSTART;
    392 	bootconfig.dram[0].pages = MEMSIZE / PAGE_SIZE;
    393 
    394         physical_start = bootconfig.dram[0].address;
    395         physical_end = physical_start + (bootconfig.dram[0].pages * PAGE_SIZE);
    396 
    397 	arm32_bootmem_init(0, physical_end, (uintptr_t) KERNEL_BASE_phys);
    398 	arm32_kernel_vm_init(KERNEL_VM_BASE, ARM_VECTORS_LOW, 0,
    399 	    devmap, false);
    400 
    401 	/* we've a specific device_register routine */
    402 	evbarm_device_register = axp_device_register;
    403 
    404 	return initarm_common(KERNEL_VM_BASE, KERNEL_VM_SIZE, NULL, 0);
    405 }
    406 
    407 #ifndef CONSADDR
    408 #error Specify the address of the UART with the CONSADDR option.
    409 #endif
    410 #ifndef CONSPEED
    411 #define	CONSPEED B115200
    412 #endif
    413 #ifndef CONMODE
    414 #define	CONMODE ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8) /* 8N1 */
    415 #endif
    416 #ifndef CONSFREQ
    417 #define	CONSFREQ 0
    418 #endif
    419 static const int	comcnspeed = CONSPEED;
    420 static const int	comcnfreq  = CONSFREQ;
    421 static const tcflag_t	comcnmode  = CONMODE;
    422 static const bus_addr_t	comcnaddr  = (bus_addr_t)CONSADDR;
    423 
    424 void
    425 consinit(void)
    426 {
    427 	static bool consinit_called = false;
    428 
    429 	if (consinit_called)
    430 		return;
    431 	consinit_called = true;
    432 
    433 #if NCOM > 0
    434 	extern int mvuart_cnattach(bus_space_tag_t, bus_addr_t, int,
    435 	    uint32_t, int);
    436 
    437 	if (mvuart_cnattach(&mvsoc_bs_tag, comcnaddr, comcnspeed,
    438 			comcnfreq ? comcnfreq : mvTclk , comcnmode))
    439 		panic("Serial console can not be initialized.");
    440 #endif
    441 }
    442 
    443 #ifdef KGDB
    444 #ifndef KGDB_DEVADDR
    445 #error Specify the address of the kgdb UART with the KGDB_DEVADDR option.
    446 #endif
    447 #ifndef KGDB_DEVRATE
    448 #define KGDB_DEVRATE B115200
    449 #endif
    450 #define MVUART_SIZE 0x20
    451 
    452 #ifndef KGDB_DEVMODE
    453 #define KGDB_DEVMODE ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8) /* 8N1 */
    454 #endif
    455 static const vaddr_t comkgdbaddr = KGDB_DEVADDR;
    456 static const int comkgdbspeed = KGDB_DEVRATE;
    457 static const int comkgdbmode = KGDB_DEVMODE;
    458 
    459 void
    460 static kgdb_port_init(void)
    461 {
    462 	static int kgdbsinit_called = 0;
    463 
    464 	if (kgdbsinit_called != 0)
    465 		return;
    466 	kgdbsinit_called = 1;
    467 
    468 	if (com_kgdb_attach(&mvsoc_bs_tag, comkgdbaddr, comkgdbspeed,
    469 			MVUART_SIZE, COM_TYPE_16550_NOERS, comkgdbmode))
    470 		panic("KGDB uart can not be initialized.");
    471 }
    472 #endif
    473 
    474 #if NMVPEX > 0
    475 static void
    476 marvell_startend_by_tag(int tag, uint64_t *start, uint64_t *end)
    477 {
    478 
    479 	uint32_t base, size;
    480 	int win;
    481 
    482 	win = mvsoc_target(tag, NULL, NULL, &base, &size);
    483 	if (size != 0) {
    484 		if (win < nremap)
    485 			*start = read_mlmbreg(MVSOC_MLMB_WRLR(win)) |
    486 			    ((read_mlmbreg(MVSOC_MLMB_WRHR(win)) << 16) << 16);
    487 		else
    488 			*start = base;
    489 		*end = *start + size - 1;
    490 	} else
    491 		*start = *end = 0;
    492 }
    493 #endif
    494 
    495 static void
    496 axp_device_register(device_t dev, void *aux)
    497 {
    498 	prop_dictionary_t dict = device_properties(dev);
    499 
    500 #if NCOM > 0
    501 	if (device_is_a(dev, "com") &&
    502 	    device_is_a(device_parent(dev), "mvsoc"))
    503 		prop_dictionary_set_uint32(dict, "frequency", mvTclk);
    504 #endif
    505 
    506 #if NMVPEX > 0
    507 	extern struct bus_space
    508 	    armadaxp_pex00_io_bs_tag, armadaxp_pex00_mem_bs_tag,
    509 	    armadaxp_pex01_io_bs_tag, armadaxp_pex01_mem_bs_tag,
    510 	    armadaxp_pex02_io_bs_tag, armadaxp_pex02_mem_bs_tag,
    511 	    armadaxp_pex03_io_bs_tag, armadaxp_pex03_mem_bs_tag,
    512 	    armadaxp_pex2_io_bs_tag, armadaxp_pex2_mem_bs_tag,
    513 	    armadaxp_pex3_io_bs_tag, armadaxp_pex3_mem_bs_tag;
    514 	extern struct arm32_pci_chipset arm32_mvpex0_chipset,
    515 	    arm32_mvpex1_chipset, arm32_mvpex2_chipset,
    516 	    arm32_mvpex3_chipset, arm32_mvpex4_chipset,
    517 	    arm32_mvpex5_chipset;
    518 
    519 	struct marvell_attach_args *mva = aux;
    520 
    521 	if (device_is_a(dev, "mvpex")) {
    522 		struct bus_space *mvpex_io_bs_tag, *mvpex_mem_bs_tag;
    523 		struct arm32_pci_chipset *arm32_mvpex_chipset;
    524 		prop_data_t io_bs_tag, mem_bs_tag, pc;
    525 		uint64_t start, end;
    526 		int iotag, memtag;
    527 
    528 		if (mva->mva_offset == MVSOC_PEX_BASE) {
    529 			mvpex_io_bs_tag = &armadaxp_pex00_io_bs_tag;
    530 			mvpex_mem_bs_tag = &armadaxp_pex00_mem_bs_tag;
    531 			arm32_mvpex_chipset = &arm32_mvpex0_chipset;
    532 			iotag = ARMADAXP_TAG_PEX00_IO;
    533 			memtag = ARMADAXP_TAG_PEX00_MEM;
    534 		} else if (mva->mva_offset == MVSOC_PEX_BASE + 0x4000) {
    535 			mvpex_io_bs_tag = &armadaxp_pex01_io_bs_tag;
    536 			mvpex_mem_bs_tag = &armadaxp_pex01_mem_bs_tag;
    537 			arm32_mvpex_chipset = &arm32_mvpex1_chipset;
    538 			iotag = ARMADAXP_TAG_PEX01_IO;
    539 			memtag = ARMADAXP_TAG_PEX01_MEM;
    540 		} else if (mva->mva_offset == MVSOC_PEX_BASE + 0x8000) {
    541 			mvpex_io_bs_tag = &armadaxp_pex02_io_bs_tag;
    542 			mvpex_mem_bs_tag = &armadaxp_pex02_mem_bs_tag;
    543 			arm32_mvpex_chipset = &arm32_mvpex2_chipset;
    544 			iotag = ARMADAXP_TAG_PEX02_IO;
    545 			memtag = ARMADAXP_TAG_PEX02_MEM;
    546 		} else if (mva->mva_offset == MVSOC_PEX_BASE + 0xc000) {
    547 			mvpex_io_bs_tag = &armadaxp_pex03_io_bs_tag;
    548 			mvpex_mem_bs_tag = &armadaxp_pex03_mem_bs_tag;
    549 			arm32_mvpex_chipset = &arm32_mvpex3_chipset;
    550 			iotag = ARMADAXP_TAG_PEX03_IO;
    551 			memtag = ARMADAXP_TAG_PEX03_MEM;
    552 		} else if (mva->mva_offset == MVSOC_PEX_BASE + 0x2000) {
    553 			mvpex_io_bs_tag = &armadaxp_pex2_io_bs_tag;
    554 			mvpex_mem_bs_tag = &armadaxp_pex2_mem_bs_tag;
    555 			arm32_mvpex_chipset = &arm32_mvpex4_chipset;
    556 			iotag = ARMADAXP_TAG_PEX2_IO;
    557 			memtag = ARMADAXP_TAG_PEX2_MEM;
    558 		} else {
    559 			mvpex_io_bs_tag = &armadaxp_pex3_io_bs_tag;
    560 			mvpex_mem_bs_tag = &armadaxp_pex3_mem_bs_tag;
    561 			arm32_mvpex_chipset = &arm32_mvpex5_chipset;
    562 			iotag = ARMADAXP_TAG_PEX3_IO;
    563 			memtag = ARMADAXP_TAG_PEX3_MEM;
    564 		}
    565 
    566 		arm32_mvpex_chipset->pc_conf_v = device_private(dev);
    567 		arm32_mvpex_chipset->pc_intr_v = device_private(dev);
    568 
    569 		io_bs_tag = prop_data_create_data_nocopy(
    570 		    mvpex_io_bs_tag, sizeof(struct bus_space));
    571 		KASSERT(io_bs_tag != NULL);
    572 		prop_dictionary_set(dict, "io-bus-tag", io_bs_tag);
    573 		prop_object_release(io_bs_tag);
    574 		mem_bs_tag = prop_data_create_data_nocopy(
    575 		    mvpex_mem_bs_tag, sizeof(struct bus_space));
    576 		KASSERT(mem_bs_tag != NULL);
    577 		prop_dictionary_set(dict, "mem-bus-tag", mem_bs_tag);
    578 		prop_object_release(mem_bs_tag);
    579 
    580 		pc = prop_data_create_data_nocopy(arm32_mvpex_chipset,
    581 		    sizeof(struct arm32_pci_chipset));
    582 		KASSERT(pc != NULL);
    583 		prop_dictionary_set(dict, "pci-chipset", pc);
    584 		prop_object_release(pc);
    585 
    586 		marvell_startend_by_tag(iotag, &start, &end);
    587 		prop_dictionary_set_uint64(dict, "iostart", start);
    588 		prop_dictionary_set_uint64(dict, "ioend", end);
    589 		marvell_startend_by_tag(memtag, &start, &end);
    590 		prop_dictionary_set_uint64(dict, "memstart", start);
    591 		prop_dictionary_set_uint64(dict, "memend", end);
    592 		prop_dictionary_set_uint32(dict,
    593 		    "cache-line-size", arm_dcache_align);
    594 	}
    595 #endif
    596 }
    597