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