diff options
Diffstat (limited to 'arch/mips/netlogic/xlp/setup.c')
| -rw-r--r-- | arch/mips/netlogic/xlp/setup.c | 155 |
1 files changed, 88 insertions, 67 deletions
diff --git a/arch/mips/netlogic/xlp/setup.c b/arch/mips/netlogic/xlp/setup.c index 4894d62043a..4fdd9fd29d1 100644 --- a/arch/mips/netlogic/xlp/setup.c +++ b/arch/mips/netlogic/xlp/setup.c @@ -33,18 +33,13 @@ */ #include <linux/kernel.h> -#include <linux/serial_8250.h> -#include <linux/pm.h> -#include <linux/bootmem.h> +#include <linux/of_fdt.h> +#include <asm/idle.h> #include <asm/reboot.h> #include <asm/time.h> #include <asm/bootinfo.h> -#include <linux/of_fdt.h> -#include <linux/of_platform.h> -#include <linux/of_device.h> - #include <asm/netlogic/haldefs.h> #include <asm/netlogic/common.h> @@ -56,41 +51,84 @@ uint64_t nlm_io_base; struct nlm_soc_info nlm_nodes[NLM_NR_NODES]; cpumask_t nlm_cpumask = CPU_MASK_CPU0; unsigned int nlm_threads_per_core; -extern u32 __dtb_start[]; +unsigned int xlp_cores_per_node; static void nlm_linux_exit(void) { uint64_t sysbase = nlm_get_node(0)->sysbase; - nlm_write_sys_reg(sysbase, SYS_CHIP_RESET, 1); + if (cpu_is_xlp9xx()) + nlm_write_sys_reg(sysbase, SYS_9XX_CHIP_RESET, 1); + else + nlm_write_sys_reg(sysbase, SYS_CHIP_RESET, 1); for ( ; ; ) cpu_wait(); } +static void nlm_fixup_mem(void) +{ + const int pref_backup = 512; + int i; + + for (i = 0; i < boot_mem_map.nr_map; i++) { + if (boot_mem_map.map[i].type != BOOT_MEM_RAM) + continue; + boot_mem_map.map[i].size -= pref_backup; + } +} + +static void __init xlp_init_mem_from_bars(void) +{ + uint64_t map[16]; + int i, n; + + n = xlp_get_dram_map(-1, map); /* -1: info for all nodes */ + for (i = 0; i < n; i += 2) { + /* exclude 0x1000_0000-0x2000_0000, u-boot device */ + if (map[i] <= 0x10000000 && map[i+1] > 0x10000000) + map[i+1] = 0x10000000; + if (map[i] > 0x10000000 && map[i] < 0x20000000) + map[i] = 0x20000000; + + add_memory_region(map[i], map[i+1] - map[i], BOOT_MEM_RAM); + } +} + void __init plat_mem_setup(void) { - void *fdtp; +#ifdef CONFIG_SMP + nlm_wakeup_secondary_cpus(); - panic_timeout = 5; + /* update TLB size after waking up threads */ + current_cpu_data.tlbsize = ((read_c0_config6() >> 16) & 0xffff) + 1; + + register_smp_ops(&nlm_smp_ops); +#endif _machine_restart = (void (*)(char *))nlm_linux_exit; _machine_halt = nlm_linux_exit; pm_power_off = nlm_linux_exit; - /* - * If no FDT pointer is passed in, use the built-in FDT. - * device_tree_init() does not handle CKSEG0 pointers in - * 64-bit, so convert pointer. - */ - fdtp = (void *)(long)fw_arg0; - if (!fdtp) - fdtp = __dtb_start; - fdtp = phys_to_virt(__pa(fdtp)); - early_init_devtree(fdtp); + /* memory and bootargs from DT */ + xlp_early_init_devtree(); + + if (boot_mem_map.nr_map == 0) { + pr_info("Using DRAM BARs for memory map.\n"); + xlp_init_mem_from_bars(); + } + /* Calculate and setup wired entries for mapped kernel */ + nlm_fixup_mem(); } const char *get_system_type(void) { - return "Netlogic XLP Series"; + switch (read_c0_prid() & PRID_IMP_MASK) { + case PRID_IMP_NETLOGIC_XLP9XX: + case PRID_IMP_NETLOGIC_XLP5XX: + case PRID_IMP_NETLOGIC_XLP2XX: + return "Broadcom XLPII Series"; + default: + return "Netlogic XLP Series"; + } } void __init prom_free_prom_memory(void) @@ -100,12 +138,20 @@ void __init prom_free_prom_memory(void) void xlp_mmu_init(void) { - /* enable extended TLB and Large Fixed TLB */ - write_c0_config6(read_c0_config6() | 0x24); - - /* set page mask of Fixed TLB in config7 */ - write_c0_config7(PM_DEFAULT_MASK >> - (13 + (ffz(PM_DEFAULT_MASK >> 13) / 2))); + u32 conf4; + + if (cpu_is_xlpii()) { + /* XLPII series has extended pagesize in config 4 */ + conf4 = read_c0_config4() & ~0x1f00u; + write_c0_config4(conf4 | ((PAGE_SHIFT - 10) / 2 << 8)); + } else { + /* enable extended TLB and Large Fixed TLB */ + write_c0_config6(read_c0_config6() | 0x24); + + /* set page mask of extended Fixed TLB in config7 */ + write_c0_config7(PM_DEFAULT_MASK >> + (13 + (ffz(PM_DEFAULT_MASK >> 13) / 2))); + } } void nlm_percpu_init(int hwcpuid) @@ -114,50 +160,25 @@ void nlm_percpu_init(int hwcpuid) void __init prom_init(void) { + void *reset_vec; + nlm_io_base = CKSEG1ADDR(XLP_DEFAULT_IO_BASE); + if (cpu_is_xlp9xx()) + xlp_cores_per_node = 32; + else + xlp_cores_per_node = 8; + nlm_init_boot_cpu(); xlp_mmu_init(); nlm_node_init(0); + xlp_dt_init((void *)(long)fw_arg0); + + /* Update reset entry point with CPU init code */ + reset_vec = (void *)CKSEG1ADDR(RESET_VEC_PHYS); + memset(reset_vec, 0, RESET_VEC_SIZE); + memcpy(reset_vec, (void *)nlm_reset_entry, + (nlm_reset_entry_end - nlm_reset_entry)); #ifdef CONFIG_SMP cpumask_setall(&nlm_cpumask); - nlm_wakeup_secondary_cpus(); - - /* update TLB size after waking up threads */ - current_cpu_data.tlbsize = ((read_c0_config6() >> 16) & 0xffff) + 1; - - register_smp_ops(&nlm_smp_ops); #endif } - -void __init device_tree_init(void) -{ - unsigned long base, size; - - if (!initial_boot_params) - return; - - base = virt_to_phys((void *)initial_boot_params); - size = be32_to_cpu(initial_boot_params->totalsize); - - /* Before we do anything, lets reserve the dt blob */ - reserve_bootmem(base, size, BOOTMEM_DEFAULT); - - unflatten_device_tree(); - - /* free the space reserved for the dt blob */ - free_bootmem(base, size); -} - -static struct of_device_id __initdata xlp_ids[] = { - { .compatible = "simple-bus", }, - {}, -}; - -int __init xlp8xx_ds_publish_devices(void) -{ - if (!of_have_populated_dt()) - return 0; - return of_platform_bus_probe(NULL, xlp_ids, NULL); -} - -device_initcall(xlp8xx_ds_publish_devices); |
