Home | History | Annotate | Line # | Download | only in armadaxp
armadaxp_machdep.c revision 1.8
      1 /*	$NetBSD: armadaxp_machdep.c,v 1.8 2014/03/29 15:00:07 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.8 2014/03/29 15:00:07 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 BootConfig bootconfig;		/* Boot config storage */
    110 char *boot_args = NULL;
    111 char *boot_file = NULL;
    112 
    113 extern int KERNEL_BASE_phys[];
    114 
    115 /*
    116  * Put some bogus settings of the MEMSTART and MEMSIZE
    117  * if they are not defined in kernel configuration file.
    118  */
    119 #ifndef MEMSTART
    120 #define MEMSTART 0x00000000UL
    121 #endif
    122 #ifndef MEMSIZE
    123 #define MEMSIZE 0x40000000UL
    124 #endif
    125 
    126 #ifndef STARTUP_PAGETABLE_ADDR
    127 #define	STARTUP_PAGETABLE_ADDR 0x00000000UL
    128 #endif
    129 
    130 /* Physical offset of the kernel from MEMSTART */
    131 #define KERNEL_OFFSET		(paddr_t)&KERNEL_BASE_phys
    132 /* Kernel base virtual address */
    133 #define	KERNEL_TEXT_BASE	(KERNEL_BASE + KERNEL_OFFSET)
    134 
    135 #define	KERNEL_VM_BASE		(KERNEL_BASE + 0x40000000)
    136 #define KERNEL_VM_SIZE		0x14000000
    137 
    138 /* Prototypes */
    139 extern int armadaxp_l2_init(bus_addr_t);
    140 extern void armadaxp_io_coherency_init(void);
    141 
    142 void consinit(void);
    143 #ifdef KGDB
    144 static void kgdb_port_init(void);
    145 #endif
    146 
    147 static void axp_device_register(device_t dev, void *aux);
    148 
    149 static void
    150 axp_system_reset(void)
    151 {
    152 	extern vaddr_t misc_base;
    153 
    154 #define write_miscreg(r, v)	(*(volatile uint32_t *)(misc_base + (r)) = (v))
    155 
    156 	cpu_reset_address = 0;
    157 
    158 	/* Unmask soft reset */
    159 	write_miscreg(ARMADAXP_MISC_RSTOUTNMASKR,
    160 	    ARMADAXP_MISC_RSTOUTNMASKR_GLOBALSOFTRSTOUTEN);
    161 	/* Assert soft reset */
    162 	write_miscreg(ARMADAXP_MISC_SSRR, ARMADAXP_MISC_SSRR_GLOBALSOFTRST);
    163 
    164 	while (1);
    165 }
    166 
    167 /*
    168  * Static device mappings. These peripheral registers are mapped at
    169  * fixed virtual addresses very early in initarm() so that we can use
    170  * them while booting the kernel, and stay at the same address
    171  * throughout whole kernel's life time.
    172  *
    173  * We use this table twice; once with bootstrap page table, and once
    174  * with kernel's page table which we build up in initarm().
    175  *
    176  * Since we map these registers into the bootstrap page table using
    177  * pmap_devmap_bootstrap() which calls pmap_map_chunk(), we map
    178  * registers segment-aligned and segment-rounded in order to avoid
    179  * using the 2nd page tables.
    180  */
    181 
    182 #define	_A(a)	((a) & ~L1_S_OFFSET)
    183 #define	_S(s)	(((s) + L1_S_SIZE - 1) & ~(L1_S_SIZE-1))
    184 
    185 static const struct pmap_devmap devmap[] = {
    186 	{
    187 		/* Internal registers */
    188 		.pd_va = _A(MARVELL_INTERREGS_VBASE),
    189 		.pd_pa = _A(MARVELL_INTERREGS_PBASE),
    190 		.pd_size = _S(MARVELL_INTERREGS_SIZE),
    191 		.pd_prot = VM_PROT_READ|VM_PROT_WRITE,
    192 		.pd_cache = PTE_NOCACHE
    193 	},
    194 	{0, 0, 0, 0, 0}
    195 };
    196 
    197 #undef	_A
    198 #undef	_S
    199 
    200 static inline pd_entry_t *
    201 read_ttb(void)
    202 {
    203 	return (pd_entry_t *)(armreg_ttbr_read() & ~((1<<14)-1));
    204 }
    205 
    206 static int
    207 axp_pcie_free_win(void)
    208 {
    209 	/* Find first disabled window */
    210 	for (size_t i = 0; i < ARMADAXP_MLMB_NWINDOW; i++) {
    211 		if ((read_mlmbreg(MVSOC_MLMB_WCR(i)) &
    212 		    MVSOC_MLMB_WCR_WINEN) == 0) {
    213 			return i;
    214 		}
    215 	}
    216 	/* If there is no free window, return erroneous value */
    217 	return (-1);
    218 }
    219 
    220 static void
    221 reset_axp_pcie_win(void)
    222 {
    223 	uint32_t target, attr;
    224 	int memtag = 0, iotag = 0, window, i;
    225 	uint32_t membase;
    226 	uint32_t iobase;
    227 	uint32_t tags[] = { ARMADAXP_TAG_PEX00_MEM, ARMADAXP_TAG_PEX00_IO,
    228 			    ARMADAXP_TAG_PEX01_MEM, ARMADAXP_TAG_PEX01_IO,
    229 			    ARMADAXP_TAG_PEX02_MEM, ARMADAXP_TAG_PEX02_IO,
    230 			    ARMADAXP_TAG_PEX03_MEM, ARMADAXP_TAG_PEX03_IO,
    231 			    ARMADAXP_TAG_PEX2_MEM, ARMADAXP_TAG_PEX2_IO,
    232 			    ARMADAXP_TAG_PEX3_MEM, ARMADAXP_TAG_PEX3_IO};
    233 
    234 	nwindow = ARMADAXP_MLMB_NWINDOW;
    235 	nremap = ARMADAXP_MLMB_NREMAP;
    236 	membase = MARVELL_PEXMEM_PBASE;
    237 	iobase = MARVELL_PEXIO_PBASE;
    238 	for (i = 0; i < __arraycount(tags) / 2; i++) {
    239 		memtag = tags[2 * i];
    240 		iotag = tags[(2 * i) + 1];
    241 
    242 		/* Reset PCI-Express space to window register. */
    243 		window = mvsoc_target(memtag, &target, &attr, NULL, NULL);
    244 
    245 		/* Find free window if we've got spurious one */
    246 		if (window >= nwindow) {
    247 			window = axp_pcie_free_win();
    248 			/* Just break if there is no free windows left */
    249 			if (window < 0) {
    250 				aprint_error(": no free windows for PEX MEM\n");
    251 				break;
    252 			}
    253 		}
    254 		write_mlmbreg(MVSOC_MLMB_WCR(window),
    255 		    MVSOC_MLMB_WCR_WINEN |
    256 		    MVSOC_MLMB_WCR_TARGET(target) |
    257 		    MVSOC_MLMB_WCR_ATTR(attr) |
    258 		    MVSOC_MLMB_WCR_SIZE(MARVELL_PEXMEM_SIZE));
    259 		write_mlmbreg(MVSOC_MLMB_WBR(window),
    260 		    membase & MVSOC_MLMB_WBR_BASE_MASK);
    261 #ifdef PCI_NETBSD_CONFIGURE
    262 		if (window < nremap) {
    263 			write_mlmbreg(MVSOC_MLMB_WRLR(window),
    264 			    membase & MVSOC_MLMB_WRLR_REMAP_MASK);
    265 			write_mlmbreg(MVSOC_MLMB_WRHR(window), 0);
    266 		}
    267 #endif
    268 		window = mvsoc_target(iotag, &target, &attr, NULL, NULL);
    269 
    270 		/* Find free window if we've got spurious one */
    271 		if (window >= nwindow) {
    272 			window = axp_pcie_free_win();
    273 			/* Just break if there is no free windows left */
    274 			if (window < 0) {
    275 				aprint_error(": no free windows for PEX I/O\n");
    276 				break;
    277 			}
    278 		}
    279 		write_mlmbreg(MVSOC_MLMB_WCR(window),
    280 		    MVSOC_MLMB_WCR_WINEN |
    281 		    MVSOC_MLMB_WCR_TARGET(target) |
    282 		    MVSOC_MLMB_WCR_ATTR(attr) |
    283 		    MVSOC_MLMB_WCR_SIZE(MARVELL_PEXIO_SIZE));
    284 		write_mlmbreg(MVSOC_MLMB_WBR(window),
    285 		    iobase & MVSOC_MLMB_WBR_BASE_MASK);
    286 #ifdef PCI_NETBSD_CONFIGURE
    287 		if (window < nremap) {
    288 			write_mlmbreg(MVSOC_MLMB_WRLR(window),
    289 			    iobase & MVSOC_MLMB_WRLR_REMAP_MASK);
    290 			write_mlmbreg(MVSOC_MLMB_WRHR(window), 0);
    291 		}
    292 #endif
    293 		membase += MARVELL_PEXMEM_SIZE;
    294 		iobase += MARVELL_PEXIO_SIZE;
    295 	}
    296 }
    297 
    298 /*
    299  * u_int initarm(...)
    300  *
    301  * Initial entry point on startup. This gets called before main() is
    302  * entered.
    303  * It should be responsible for setting up everything that must be
    304  * in place when main is called.
    305  * This includes
    306  *   Taking a copy of the boot configuration structure.
    307  *   Initialising the physical console so characters can be printed.
    308  *   Setting up page tables for the kernel
    309  *   Relocating the kernel to the bottom of physical memory
    310  */
    311 u_int
    312 initarm(void *arg)
    313 {
    314 	cpu_reset_address = axp_system_reset;
    315 
    316 	mvsoc_bootstrap(MARVELL_INTERREGS_VBASE);
    317 
    318 	/* Set CPU functions */
    319 	if (set_cpufuncs())
    320 		panic("cpu not recognized!");
    321 
    322 	/*
    323 	 * Map devices into the initial page table
    324 	 * in order to use early console during initialization process.
    325 	 * consinit is going to use this mapping.
    326 	 */
    327 	pmap_devmap_bootstrap((vaddr_t)read_ttb(), devmap);
    328 
    329 	/* Initialize system console */
    330 	consinit();
    331 
    332 	/* Reset PCI-Express space to window register. */
    333 	reset_axp_pcie_win();
    334 
    335 	/* Get CPU, system and timebase frequencies */
    336 	extern vaddr_t misc_base;
    337 	misc_base = MARVELL_INTERREGS_VBASE + ARMADAXP_MISC_BASE;
    338 	armadaxp_getclks();
    339 	mvsoc_clkgating = armadaxp_clkgating;
    340 
    341 	/* Preconfigure interrupts */
    342 	armadaxp_intr_bootstrap(MARVELL_INTERREGS_PBASE);
    343 
    344 #ifdef L2CACHE_ENABLE
    345 	/* Initialize L2 Cache */
    346 	(void)armadaxp_l2_init(MARVELL_INTERREGS_PBASE);
    347 #endif
    348 
    349 #ifdef AURORA_IO_CACHE_COHERENCY
    350 	/* Initialize cache coherency */
    351 	armadaxp_io_coherency_init();
    352 #endif
    353 
    354 #ifdef KGDB
    355 	kgdb_port_init();
    356 #endif
    357 
    358 #ifdef VERBOSE_INIT_ARM
    359 	/* Talk to the user */
    360 #define	BDSTR(s)	_BDSTR(s)
    361 #define	_BDSTR(s)	#s
    362 	printf("\nNetBSD/evbarm (" BDSTR(EVBARM_BOARDTYPE) ") booting ...\n");
    363 #endif
    364 
    365 #ifdef __HAVE_MM_MD_DIRECT_MAPPED_PHYS
    366 	const bool mapallmem_p = true;
    367 #else
    368 	const bool mapallmem_p = false;
    369 #endif
    370 
    371 #ifdef VERBOSE_INIT_ARM
    372 	printf("initarm: Configuring system ...\n");
    373 #endif
    374 	psize_t memsize = MEMSIZE;
    375 	if (mapallmem_p && memsize > KERNEL_VM_BASE - KERNEL_BASE) {
    376 		printf("%s: dropping RAM size from %luMB to %uMB\n",
    377 		    __func__, (unsigned long) (memsize >> 20),
    378 		    (KERNEL_VM_BASE - KERNEL_BASE) >> 20);
    379 		memsize = KERNEL_VM_BASE - KERNEL_BASE;
    380 	}
    381 	/* Fake bootconfig structure for the benefit of pmap.c. */
    382 	bootconfig.dramblocks = 1;
    383 	bootconfig.dram[0].address = MEMSTART;
    384 	bootconfig.dram[0].pages = memsize / PAGE_SIZE;
    385 
    386         physical_start = bootconfig.dram[0].address;
    387         physical_end = physical_start + (bootconfig.dram[0].pages * PAGE_SIZE);
    388 
    389 	arm32_bootmem_init(0, physical_end, (uintptr_t) KERNEL_BASE_phys);
    390 	arm32_kernel_vm_init(KERNEL_VM_BASE, ARM_VECTORS_LOW, 0,
    391 	    devmap, mapallmem_p);
    392 
    393 	/* we've a specific device_register routine */
    394 	evbarm_device_register = axp_device_register;
    395 
    396 	return initarm_common(KERNEL_VM_BASE, KERNEL_VM_SIZE, NULL, 0);
    397 }
    398 
    399 #ifndef CONSADDR
    400 #error Specify the address of the UART with the CONSADDR option.
    401 #endif
    402 #ifndef CONSPEED
    403 #define	CONSPEED B115200
    404 #endif
    405 #ifndef CONMODE
    406 #define	CONMODE ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8) /* 8N1 */
    407 #endif
    408 #ifndef CONSFREQ
    409 #define	CONSFREQ 0
    410 #endif
    411 static const int	comcnspeed = CONSPEED;
    412 static const int	comcnfreq  = CONSFREQ;
    413 static const tcflag_t	comcnmode  = CONMODE;
    414 static const bus_addr_t	comcnaddr  = (bus_addr_t)CONSADDR;
    415 
    416 void
    417 consinit(void)
    418 {
    419 	static bool consinit_called = false;
    420 
    421 	if (consinit_called)
    422 		return;
    423 	consinit_called = true;
    424 
    425 #if NCOM > 0
    426 	extern int mvuart_cnattach(bus_space_tag_t, bus_addr_t, int,
    427 	    uint32_t, int);
    428 
    429 	if (mvuart_cnattach(&mvsoc_bs_tag, comcnaddr, comcnspeed,
    430 			comcnfreq ? comcnfreq : mvTclk , comcnmode))
    431 		panic("Serial console can not be initialized.");
    432 #endif
    433 }
    434 
    435 #ifdef KGDB
    436 #ifndef KGDB_DEVADDR
    437 #error Specify the address of the kgdb UART with the KGDB_DEVADDR option.
    438 #endif
    439 #ifndef KGDB_DEVRATE
    440 #define KGDB_DEVRATE B115200
    441 #endif
    442 #define MVUART_SIZE 0x20
    443 
    444 #ifndef KGDB_DEVMODE
    445 #define KGDB_DEVMODE ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8) /* 8N1 */
    446 #endif
    447 static const vaddr_t comkgdbaddr = KGDB_DEVADDR;
    448 static const int comkgdbspeed = KGDB_DEVRATE;
    449 static const int comkgdbmode = KGDB_DEVMODE;
    450 
    451 void
    452 static kgdb_port_init(void)
    453 {
    454 	static int kgdbsinit_called = 0;
    455 
    456 	if (kgdbsinit_called != 0)
    457 		return;
    458 	kgdbsinit_called = 1;
    459 
    460 	if (com_kgdb_attach(&mvsoc_bs_tag, comkgdbaddr, comkgdbspeed,
    461 			MVUART_SIZE, COM_TYPE_16550_NOERS, comkgdbmode))
    462 		panic("KGDB uart can not be initialized.");
    463 }
    464 #endif
    465 
    466 #if NMVPEX > 0
    467 static void
    468 marvell_startend_by_tag(int tag, uint64_t *start, uint64_t *end)
    469 {
    470 
    471 	uint32_t base, size;
    472 	int win;
    473 
    474 	win = mvsoc_target(tag, NULL, NULL, &base, &size);
    475 	if (size != 0) {
    476 		if (win < nremap)
    477 			*start = read_mlmbreg(MVSOC_MLMB_WRLR(win)) |
    478 			    ((read_mlmbreg(MVSOC_MLMB_WRHR(win)) << 16) << 16);
    479 		else
    480 			*start = base;
    481 		*end = *start + size - 1;
    482 	} else
    483 		*start = *end = 0;
    484 }
    485 #endif
    486 
    487 static void
    488 axp_device_register(device_t dev, void *aux)
    489 {
    490 	prop_dictionary_t dict = device_properties(dev);
    491 
    492 #if NCOM > 0
    493 	if (device_is_a(dev, "com") &&
    494 	    device_is_a(device_parent(dev), "mvsoc"))
    495 		prop_dictionary_set_uint32(dict, "frequency", mvTclk);
    496 #endif
    497 
    498 #if NMVPEX > 0
    499 	extern struct bus_space
    500 	    armadaxp_pex00_io_bs_tag, armadaxp_pex00_mem_bs_tag,
    501 	    armadaxp_pex01_io_bs_tag, armadaxp_pex01_mem_bs_tag,
    502 	    armadaxp_pex02_io_bs_tag, armadaxp_pex02_mem_bs_tag,
    503 	    armadaxp_pex03_io_bs_tag, armadaxp_pex03_mem_bs_tag,
    504 	    armadaxp_pex2_io_bs_tag, armadaxp_pex2_mem_bs_tag,
    505 	    armadaxp_pex3_io_bs_tag, armadaxp_pex3_mem_bs_tag;
    506 	extern struct arm32_pci_chipset arm32_mvpex0_chipset,
    507 	    arm32_mvpex1_chipset, arm32_mvpex2_chipset,
    508 	    arm32_mvpex3_chipset, arm32_mvpex4_chipset,
    509 	    arm32_mvpex5_chipset;
    510 
    511 	struct marvell_attach_args *mva = aux;
    512 
    513 	if (device_is_a(dev, "mvpex")) {
    514 		struct bus_space *mvpex_io_bs_tag, *mvpex_mem_bs_tag;
    515 		struct arm32_pci_chipset *arm32_mvpex_chipset;
    516 		prop_data_t io_bs_tag, mem_bs_tag, pc;
    517 		uint64_t start, end;
    518 		int iotag, memtag;
    519 
    520 		if (mva->mva_offset == MVSOC_PEX_BASE) {
    521 			mvpex_io_bs_tag = &armadaxp_pex00_io_bs_tag;
    522 			mvpex_mem_bs_tag = &armadaxp_pex00_mem_bs_tag;
    523 			arm32_mvpex_chipset = &arm32_mvpex0_chipset;
    524 			iotag = ARMADAXP_TAG_PEX00_IO;
    525 			memtag = ARMADAXP_TAG_PEX00_MEM;
    526 		} else if (mva->mva_offset == MVSOC_PEX_BASE + 0x4000) {
    527 			mvpex_io_bs_tag = &armadaxp_pex01_io_bs_tag;
    528 			mvpex_mem_bs_tag = &armadaxp_pex01_mem_bs_tag;
    529 			arm32_mvpex_chipset = &arm32_mvpex1_chipset;
    530 			iotag = ARMADAXP_TAG_PEX01_IO;
    531 			memtag = ARMADAXP_TAG_PEX01_MEM;
    532 		} else if (mva->mva_offset == MVSOC_PEX_BASE + 0x8000) {
    533 			mvpex_io_bs_tag = &armadaxp_pex02_io_bs_tag;
    534 			mvpex_mem_bs_tag = &armadaxp_pex02_mem_bs_tag;
    535 			arm32_mvpex_chipset = &arm32_mvpex2_chipset;
    536 			iotag = ARMADAXP_TAG_PEX02_IO;
    537 			memtag = ARMADAXP_TAG_PEX02_MEM;
    538 		} else if (mva->mva_offset == MVSOC_PEX_BASE + 0xc000) {
    539 			mvpex_io_bs_tag = &armadaxp_pex03_io_bs_tag;
    540 			mvpex_mem_bs_tag = &armadaxp_pex03_mem_bs_tag;
    541 			arm32_mvpex_chipset = &arm32_mvpex3_chipset;
    542 			iotag = ARMADAXP_TAG_PEX03_IO;
    543 			memtag = ARMADAXP_TAG_PEX03_MEM;
    544 		} else if (mva->mva_offset == MVSOC_PEX_BASE + 0x2000) {
    545 			mvpex_io_bs_tag = &armadaxp_pex2_io_bs_tag;
    546 			mvpex_mem_bs_tag = &armadaxp_pex2_mem_bs_tag;
    547 			arm32_mvpex_chipset = &arm32_mvpex4_chipset;
    548 			iotag = ARMADAXP_TAG_PEX2_IO;
    549 			memtag = ARMADAXP_TAG_PEX2_MEM;
    550 		} else {
    551 			mvpex_io_bs_tag = &armadaxp_pex3_io_bs_tag;
    552 			mvpex_mem_bs_tag = &armadaxp_pex3_mem_bs_tag;
    553 			arm32_mvpex_chipset = &arm32_mvpex5_chipset;
    554 			iotag = ARMADAXP_TAG_PEX3_IO;
    555 			memtag = ARMADAXP_TAG_PEX3_MEM;
    556 		}
    557 
    558 		arm32_mvpex_chipset->pc_conf_v = device_private(dev);
    559 		arm32_mvpex_chipset->pc_intr_v = device_private(dev);
    560 
    561 		io_bs_tag = prop_data_create_data_nocopy(
    562 		    mvpex_io_bs_tag, sizeof(struct bus_space));
    563 		KASSERT(io_bs_tag != NULL);
    564 		prop_dictionary_set(dict, "io-bus-tag", io_bs_tag);
    565 		prop_object_release(io_bs_tag);
    566 		mem_bs_tag = prop_data_create_data_nocopy(
    567 		    mvpex_mem_bs_tag, sizeof(struct bus_space));
    568 		KASSERT(mem_bs_tag != NULL);
    569 		prop_dictionary_set(dict, "mem-bus-tag", mem_bs_tag);
    570 		prop_object_release(mem_bs_tag);
    571 
    572 		pc = prop_data_create_data_nocopy(arm32_mvpex_chipset,
    573 		    sizeof(struct arm32_pci_chipset));
    574 		KASSERT(pc != NULL);
    575 		prop_dictionary_set(dict, "pci-chipset", pc);
    576 		prop_object_release(pc);
    577 
    578 		marvell_startend_by_tag(iotag, &start, &end);
    579 		prop_dictionary_set_uint64(dict, "iostart", start);
    580 		prop_dictionary_set_uint64(dict, "ioend", end);
    581 		marvell_startend_by_tag(memtag, &start, &end);
    582 		prop_dictionary_set_uint64(dict, "memstart", start);
    583 		prop_dictionary_set_uint64(dict, "memend", end);
    584 		prop_dictionary_set_uint32(dict,
    585 		    "cache-line-size", arm_dcache_align);
    586 	}
    587 #endif
    588 }
    589