Home | History | Annotate | Line # | Download | only in armadaxp
armadaxp_machdep.c revision 1.5
      1 /*	$NetBSD: armadaxp_machdep.c,v 1.5 2013/12/23 03:19:43 kiyohara 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.5 2013/12/23 03:19:43 kiyohara 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 
    360 	/* Preconfigure interrupts */
    361 	armadaxp_intr_bootstrap(MARVELL_INTERREGS_PBASE);
    362 
    363 #ifdef L2CACHE_ENABLE
    364 	/* Initialize L2 Cache */
    365 	(void)armadaxp_l2_init(MARVELL_INTERREGS_PBASE);
    366 #endif
    367 
    368 #ifdef AURORA_IO_CACHE_COHERENCY
    369 	/* Initialize cache coherency */
    370 	armadaxp_io_coherency_init();
    371 #endif
    372 
    373 #ifdef KGDB
    374 	kgdb_port_init();
    375 #endif
    376 
    377 #ifdef VERBOSE_INIT_ARM
    378 	/* Talk to the user */
    379 #define	BDSTR(s)	_BDSTR(s)
    380 #define	_BDSTR(s)	#s
    381 	printf("\nNetBSD/evbarm (" BDSTR(EVBARM_BOARDTYPE) ") booting ...\n");
    382 #endif
    383 
    384 
    385 #ifdef VERBOSE_INIT_ARM
    386 	printf("initarm: Configuring system ...\n");
    387 #endif
    388 	/* Fake bootconfig structure for the benefit of pmap.c. */
    389 	bootconfig.dramblocks = 1;
    390 	bootconfig.dram[0].address = MEMSTART;
    391 	bootconfig.dram[0].pages = MEMSIZE / PAGE_SIZE;
    392 
    393         physical_start = bootconfig.dram[0].address;
    394         physical_end = physical_start + (bootconfig.dram[0].pages * PAGE_SIZE);
    395 
    396 	arm32_bootmem_init(0, physical_end, (uintptr_t) KERNEL_BASE_phys);
    397 	arm32_kernel_vm_init(KERNEL_VM_BASE, ARM_VECTORS_LOW, 0,
    398 	    devmap, false);
    399 
    400 	/* we've a specific device_register routine */
    401 	evbarm_device_register = axp_device_register;
    402 
    403 	return initarm_common(KERNEL_VM_BASE, KERNEL_VM_SIZE, NULL, 0);
    404 }
    405 
    406 #ifndef CONSADDR
    407 #error Specify the address of the UART with the CONSADDR option.
    408 #endif
    409 #ifndef CONSPEED
    410 #define	CONSPEED B115200
    411 #endif
    412 #ifndef CONMODE
    413 #define	CONMODE ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8) /* 8N1 */
    414 #endif
    415 #ifndef CONSFREQ
    416 #define	CONSFREQ 250000000
    417 #endif
    418 static const int	comcnspeed = CONSPEED;
    419 static const int	comcnfreq  = CONSFREQ;
    420 static const tcflag_t	comcnmode  = CONMODE;
    421 static const bus_addr_t	comcnaddr  = (bus_addr_t)CONSADDR;
    422 
    423 void
    424 consinit(void)
    425 {
    426 	static bool consinit_called = false;
    427 
    428 	if (consinit_called)
    429 		return;
    430 	consinit_called = true;
    431 
    432 #if NCOM > 0
    433 	extern int mvuart_cnattach(bus_space_tag_t, bus_addr_t, int,
    434 	    uint32_t, int);
    435 
    436 	if (mvuart_cnattach(&mvsoc_bs_tag, comcnaddr, comcnspeed,
    437 			comcnfreq, comcnmode))
    438 		panic("Serial console can not be initialized.");
    439 #endif
    440 }
    441 
    442 #ifdef KGDB
    443 #ifndef KGDB_DEVADDR
    444 #error Specify the address of the kgdb UART with the KGDB_DEVADDR option.
    445 #endif
    446 #ifndef KGDB_DEVRATE
    447 #define KGDB_DEVRATE B115200
    448 #endif
    449 #define MVUART_SIZE 0x20
    450 
    451 #ifndef KGDB_DEVMODE
    452 #define KGDB_DEVMODE ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8) /* 8N1 */
    453 #endif
    454 static const vaddr_t comkgdbaddr = KGDB_DEVADDR;
    455 static const int comkgdbspeed = KGDB_DEVRATE;
    456 static const int comkgdbmode = KGDB_DEVMODE;
    457 
    458 void
    459 static kgdb_port_init(void)
    460 {
    461 	static int kgdbsinit_called = 0;
    462 
    463 	if (kgdbsinit_called != 0)
    464 		return;
    465 	kgdbsinit_called = 1;
    466 
    467 	if (com_kgdb_attach(&mvsoc_bs_tag, comkgdbaddr, comkgdbspeed,
    468 			MVUART_SIZE, COM_TYPE_16550_NOERS, comkgdbmode))
    469 		panic("KGDB uart can not be initialized.");
    470 }
    471 #endif
    472 
    473 #if NMVPEX > 0
    474 static void
    475 marvell_startend_by_tag(int tag, uint64_t *start, uint64_t *end)
    476 {
    477 
    478 	uint32_t base, size;
    479 	int win;
    480 
    481 	win = mvsoc_target(tag, NULL, NULL, &base, &size);
    482 	if (size != 0) {
    483 		if (win < nremap)
    484 			*start = read_mlmbreg(MVSOC_MLMB_WRLR(win)) |
    485 			    ((read_mlmbreg(MVSOC_MLMB_WRHR(win)) << 16) << 16);
    486 		else
    487 			*start = base;
    488 		*end = *start + size - 1;
    489 	} else
    490 		*start = *end = 0;
    491 }
    492 #endif
    493 
    494 static void
    495 axp_device_register(device_t dev, void *aux)
    496 {
    497 	prop_dictionary_t dict = device_properties(dev);
    498 
    499 #if NCOM > 0
    500 	if (device_is_a(dev, "com") &&
    501 	    device_is_a(device_parent(dev), "mvsoc"))
    502 		prop_dictionary_set_uint32(dict, "frequency", mvTclk);
    503 #endif
    504 
    505 #if NMVPEX > 0
    506 	extern struct bus_space
    507 	    armadaxp_pex00_io_bs_tag, armadaxp_pex00_mem_bs_tag,
    508 	    armadaxp_pex01_io_bs_tag, armadaxp_pex01_mem_bs_tag,
    509 	    armadaxp_pex02_io_bs_tag, armadaxp_pex02_mem_bs_tag,
    510 	    armadaxp_pex03_io_bs_tag, armadaxp_pex03_mem_bs_tag,
    511 	    armadaxp_pex2_io_bs_tag, armadaxp_pex2_mem_bs_tag,
    512 	    armadaxp_pex3_io_bs_tag, armadaxp_pex3_mem_bs_tag;
    513 	extern struct arm32_pci_chipset arm32_mvpex0_chipset,
    514 	    arm32_mvpex1_chipset, arm32_mvpex2_chipset,
    515 	    arm32_mvpex3_chipset, arm32_mvpex4_chipset,
    516 	    arm32_mvpex5_chipset;
    517 
    518 	struct marvell_attach_args *mva = aux;
    519 
    520 	if (device_is_a(dev, "mvpex")) {
    521 		struct bus_space *mvpex_io_bs_tag, *mvpex_mem_bs_tag;
    522 		struct arm32_pci_chipset *arm32_mvpex_chipset;
    523 		prop_data_t io_bs_tag, mem_bs_tag, pc;
    524 		uint64_t start, end;
    525 		int iotag, memtag;
    526 
    527 		if (mva->mva_offset == MVSOC_PEX_BASE) {
    528 			mvpex_io_bs_tag = &armadaxp_pex00_io_bs_tag;
    529 			mvpex_mem_bs_tag = &armadaxp_pex00_mem_bs_tag;
    530 			arm32_mvpex_chipset = &arm32_mvpex0_chipset;
    531 			iotag = ARMADAXP_TAG_PEX00_IO;
    532 			memtag = ARMADAXP_TAG_PEX00_MEM;
    533 		} else if (mva->mva_offset == MVSOC_PEX_BASE + 0x4000) {
    534 			mvpex_io_bs_tag = &armadaxp_pex01_io_bs_tag;
    535 			mvpex_mem_bs_tag = &armadaxp_pex01_mem_bs_tag;
    536 			arm32_mvpex_chipset = &arm32_mvpex1_chipset;
    537 			iotag = ARMADAXP_TAG_PEX01_IO;
    538 			memtag = ARMADAXP_TAG_PEX01_MEM;
    539 		} else if (mva->mva_offset == MVSOC_PEX_BASE + 0x8000) {
    540 			mvpex_io_bs_tag = &armadaxp_pex02_io_bs_tag;
    541 			mvpex_mem_bs_tag = &armadaxp_pex02_mem_bs_tag;
    542 			arm32_mvpex_chipset = &arm32_mvpex2_chipset;
    543 			iotag = ARMADAXP_TAG_PEX02_IO;
    544 			memtag = ARMADAXP_TAG_PEX02_MEM;
    545 		} else if (mva->mva_offset == MVSOC_PEX_BASE + 0xc000) {
    546 			mvpex_io_bs_tag = &armadaxp_pex03_io_bs_tag;
    547 			mvpex_mem_bs_tag = &armadaxp_pex03_mem_bs_tag;
    548 			arm32_mvpex_chipset = &arm32_mvpex3_chipset;
    549 			iotag = ARMADAXP_TAG_PEX03_IO;
    550 			memtag = ARMADAXP_TAG_PEX03_MEM;
    551 		} else if (mva->mva_offset == MVSOC_PEX_BASE + 0x2000) {
    552 			mvpex_io_bs_tag = &armadaxp_pex2_io_bs_tag;
    553 			mvpex_mem_bs_tag = &armadaxp_pex2_mem_bs_tag;
    554 			arm32_mvpex_chipset = &arm32_mvpex4_chipset;
    555 			iotag = ARMADAXP_TAG_PEX2_IO;
    556 			memtag = ARMADAXP_TAG_PEX2_MEM;
    557 		} else {
    558 			mvpex_io_bs_tag = &armadaxp_pex3_io_bs_tag;
    559 			mvpex_mem_bs_tag = &armadaxp_pex3_mem_bs_tag;
    560 			arm32_mvpex_chipset = &arm32_mvpex5_chipset;
    561 			iotag = ARMADAXP_TAG_PEX3_IO;
    562 			memtag = ARMADAXP_TAG_PEX3_MEM;
    563 		}
    564 
    565 		arm32_mvpex_chipset->pc_conf_v = device_private(dev);
    566 		arm32_mvpex_chipset->pc_intr_v = device_private(dev);
    567 
    568 		io_bs_tag = prop_data_create_data_nocopy(
    569 		    mvpex_io_bs_tag, sizeof(struct bus_space));
    570 		KASSERT(io_bs_tag != NULL);
    571 		prop_dictionary_set(dict, "io-bus-tag", io_bs_tag);
    572 		prop_object_release(io_bs_tag);
    573 		mem_bs_tag = prop_data_create_data_nocopy(
    574 		    mvpex_mem_bs_tag, sizeof(struct bus_space));
    575 		KASSERT(mem_bs_tag != NULL);
    576 		prop_dictionary_set(dict, "mem-bus-tag", mem_bs_tag);
    577 		prop_object_release(mem_bs_tag);
    578 
    579 		pc = prop_data_create_data_nocopy(arm32_mvpex_chipset,
    580 		    sizeof(struct arm32_pci_chipset));
    581 		KASSERT(pc != NULL);
    582 		prop_dictionary_set(dict, "pci-chipset", pc);
    583 		prop_object_release(pc);
    584 
    585 		marvell_startend_by_tag(iotag, &start, &end);
    586 		prop_dictionary_set_uint64(dict, "iostart", start);
    587 		prop_dictionary_set_uint64(dict, "ioend", end);
    588 		marvell_startend_by_tag(memtag, &start, &end);
    589 		prop_dictionary_set_uint64(dict, "memstart", start);
    590 		prop_dictionary_set_uint64(dict, "memend", end);
    591 		prop_dictionary_set_uint32(dict,
    592 		    "cache-line-size", arm_dcache_align);
    593 	}
    594 #endif
    595 }
    596