15c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C/* 25c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C * Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). All rights 35c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C * reserved. 45c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C * 55c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C * This software is available to you under a choice of one of two 65c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C * licenses. You may choose to be licensed under the terms of the GNU 75c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C * General Public License (GPL) Version 2, available from the file 85c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C * COPYING in the main directory of this source tree, or the NetLogic 95c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C * license below: 105c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C * 115c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C * Redistribution and use in source and binary forms, with or without 125c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C * modification, are permitted provided that the following conditions 135c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C * are met: 145c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C * 155c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C * 1. Redistributions of source code must retain the above copyright 165c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C * notice, this list of conditions and the following disclaimer. 175c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C * 2. Redistributions in binary form must reproduce the above copyright 185c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C * notice, this list of conditions and the following disclaimer in 195c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C * the documentation and/or other materials provided with the 205c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C * distribution. 215c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C * 225c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C * THIS SOFTWARE IS PROVIDED BY NETLOGIC ``AS IS'' AND ANY EXPRESS OR 235c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 245c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 255c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C * ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE LIABLE 265c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 275c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 285c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 295c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 305c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 315c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 325c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 335c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C */ 345c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C 355c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C#include <linux/kernel.h> 365c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C#include <linux/serial_8250.h> 375c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C#include <linux/pm.h> 385c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C 39bdc92d74e0ec95a8101447467c25f015105f2e5aRalf Baechle#include <asm/idle.h> 405c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C#include <asm/reboot.h> 415c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C#include <asm/time.h> 425c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C#include <asm/bootinfo.h> 435c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C 445c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C#include <asm/netlogic/interrupt.h> 455c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C#include <asm/netlogic/psb-bootinfo.h> 460c9654072a6e15aa3da9b314f0c5c01e90938268Jayachandran C#include <asm/netlogic/haldefs.h> 470c9654072a6e15aa3da9b314f0c5c01e90938268Jayachandran C#include <asm/netlogic/common.h> 485c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C 495c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C#include <asm/netlogic/xlr/xlr.h> 505c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C#include <asm/netlogic/xlr/iomap.h> 515c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C#include <asm/netlogic/xlr/pic.h> 525c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C#include <asm/netlogic/xlr/gpio.h> 53ed21cfe207276e2d2883173399dd0380db372e18Ganesan Ramalingam#include <asm/netlogic/xlr/fmn.h> 545c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C 550c9654072a6e15aa3da9b314f0c5c01e90938268Jayachandran Cuint64_t nlm_io_base = DEFAULT_NETLOGIC_IO_BASE; 565c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran Cstruct psb_info nlm_prom_info; 575c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C 5866d29985fab8207b1b2c03ac34a2c294c5b47a30Jayachandran C/* default to uniprocessor */ 5977ae798f5b736dfdc692b86b393d9699052ac77aJayachandran Cunsigned int nlm_threads_per_core = 1; 6077ae798f5b736dfdc692b86b393d9699052ac77aJayachandran Cstruct nlm_soc_info nlm_nodes[NLM_NR_NODES]; 612a37b1ae443f20470a789b12a45cbc249c9e50a6Jayachandran Ccpumask_t nlm_cpumask = CPU_MASK_CPU0; 6266d29985fab8207b1b2c03ac34a2c294c5b47a30Jayachandran C 635c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran Cstatic void nlm_linux_exit(void) 645c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C{ 650c9654072a6e15aa3da9b314f0c5c01e90938268Jayachandran C uint64_t gpiobase; 665c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C 670c9654072a6e15aa3da9b314f0c5c01e90938268Jayachandran C gpiobase = nlm_mmio_base(NETLOGIC_IO_GPIO_OFFSET); 685c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C /* trigger a chip reset by writing 1 to GPIO_SWRESET_REG */ 69c5a48ff81e25c8585dae981a6cc19ed55788cadfJayachandran C nlm_write_reg(gpiobase, GPIO_SWRESET_REG, 1); 705c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C for ( ; ; ) 715c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C cpu_wait(); 725c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C} 735c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C 745c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran Cvoid __init plat_mem_setup(void) 755c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C{ 765c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C _machine_restart = (void (*)(char *))nlm_linux_exit; 775c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C _machine_halt = nlm_linux_exit; 785c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C pm_power_off = nlm_linux_exit; 795c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C} 805c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C 815c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran Cconst char *get_system_type(void) 825c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C{ 835c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C return "Netlogic XLR/XLS Series"; 845c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C} 855c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C 860c9654072a6e15aa3da9b314f0c5c01e90938268Jayachandran Cunsigned int nlm_get_cpu_frequency(void) 870c9654072a6e15aa3da9b314f0c5c01e90938268Jayachandran C{ 880c9654072a6e15aa3da9b314f0c5c01e90938268Jayachandran C return (unsigned int)nlm_prom_info.cpu_frequency; 890c9654072a6e15aa3da9b314f0c5c01e90938268Jayachandran C} 900c9654072a6e15aa3da9b314f0c5c01e90938268Jayachandran C 915c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran Cvoid __init prom_free_prom_memory(void) 925c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C{ 935c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C /* Nothing yet */ 945c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C} 955c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C 96ed21cfe207276e2d2883173399dd0380db372e18Ganesan Ramalingamvoid nlm_percpu_init(int hwcpuid) 97ed21cfe207276e2d2883173399dd0380db372e18Ganesan Ramalingam{ 98ed21cfe207276e2d2883173399dd0380db372e18Ganesan Ramalingam if (hwcpuid % 4 == 0) 99ed21cfe207276e2d2883173399dd0380db372e18Ganesan Ramalingam xlr_percpu_fmn_init(); 100ed21cfe207276e2d2883173399dd0380db372e18Ganesan Ramalingam} 101ed21cfe207276e2d2883173399dd0380db372e18Ganesan Ramalingam 102a74e33535fa27c758d2a23ebf5f8964bf19940bcJayachandran Cstatic void __init build_arcs_cmdline(int *argv) 1035c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C{ 1045c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C int i, remain, len; 1055c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C char *arg; 1065c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C 1075c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C remain = sizeof(arcs_cmdline) - 1; 1085c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C arcs_cmdline[0] = '\0'; 1095c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C for (i = 0; argv[i] != 0; i++) { 1105c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C arg = (char *)(long)argv[i]; 1115c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C len = strlen(arg); 1125c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C if (len + 1 > remain) 1135c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C break; 1145c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C strcat(arcs_cmdline, arg); 1155c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C strcat(arcs_cmdline, " "); 1165c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C remain -= len + 1; 1175c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C } 1185c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C 1195c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C /* Add the default options here */ 1205c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C if ((strstr(arcs_cmdline, "console=")) == NULL) { 1215c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C arg = "console=ttyS0,38400 "; 1225c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C len = strlen(arg); 1235c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C if (len > remain) 1245c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C goto fail; 1255c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C strcat(arcs_cmdline, arg); 1265c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C remain -= len; 1275c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C } 1285c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C#ifdef CONFIG_BLK_DEV_INITRD 1295c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C if ((strstr(arcs_cmdline, "rdinit=")) == NULL) { 1305c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C arg = "rdinit=/sbin/init "; 1315c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C len = strlen(arg); 1325c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C if (len > remain) 1335c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C goto fail; 1345c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C strcat(arcs_cmdline, arg); 1355c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C remain -= len; 1365c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C } 1375c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C#endif 1385c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C return; 1395c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran Cfail: 1405c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C panic("Cannot add %s, command line too big!", arg); 1415c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C} 1425c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C 1435c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran Cstatic void prom_add_memory(void) 1445c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C{ 1455c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C struct nlm_boot_mem_map *bootm; 1465c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C u64 start, size; 1477034228792cc561e79ff8600f02884bd4c80e287Ralf Baechle u64 pref_backup = 512; /* avoid pref walking beyond end */ 1485c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C int i; 1495c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C 1505c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C bootm = (void *)(long)nlm_prom_info.psb_mem_map; 1515c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C for (i = 0; i < bootm->nr_map; i++) { 1525c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C if (bootm->map[i].type != BOOT_MEM_RAM) 1535c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C continue; 1545c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C start = bootm->map[i].addr; 1555c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C size = bootm->map[i].size; 1565c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C 1575c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C /* Work around for using bootloader mem */ 1585c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C if (i == 0 && start == 0 && size == 0x0c000000) 1595c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C size = 0x0ff00000; 1605c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C 1615c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C add_memory_region(start, size - pref_backup, BOOT_MEM_RAM); 1625c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C } 1635c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C} 1645c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C 16577ae798f5b736dfdc692b86b393d9699052ac77aJayachandran Cstatic void nlm_init_node(void) 16677ae798f5b736dfdc692b86b393d9699052ac77aJayachandran C{ 16777ae798f5b736dfdc692b86b393d9699052ac77aJayachandran C struct nlm_soc_info *nodep; 16877ae798f5b736dfdc692b86b393d9699052ac77aJayachandran C 16977ae798f5b736dfdc692b86b393d9699052ac77aJayachandran C nodep = nlm_current_node(); 17077ae798f5b736dfdc692b86b393d9699052ac77aJayachandran C nodep->picbase = nlm_mmio_base(NETLOGIC_IO_PIC_OFFSET); 17177ae798f5b736dfdc692b86b393d9699052ac77aJayachandran C nodep->ebase = read_c0_ebase() & (~((1 << 12) - 1)); 17277ae798f5b736dfdc692b86b393d9699052ac77aJayachandran C spin_lock_init(&nodep->piclock); 17377ae798f5b736dfdc692b86b393d9699052ac77aJayachandran C} 17477ae798f5b736dfdc692b86b393d9699052ac77aJayachandran C 1755c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran Cvoid __init prom_init(void) 1765c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C{ 17726f5ae865d7b324e46fff91acf43c485939bf6eaJayachandran C int *argv, *envp; /* passed as 32 bit ptrs */ 1785c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C struct psb_info *prom_infop; 179571886b2a52395f030d439c6259663a033e11e6aJayachandran C void *reset_vec; 18026f5ae865d7b324e46fff91acf43c485939bf6eaJayachandran C#ifdef CONFIG_SMP 18126f5ae865d7b324e46fff91acf43c485939bf6eaJayachandran C int i; 18226f5ae865d7b324e46fff91acf43c485939bf6eaJayachandran C#endif 1835c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C 1845c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C /* truncate to 32 bit and sign extend all args */ 1855c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C argv = (int *)(long)(int)fw_arg1; 1865c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C envp = (int *)(long)(int)fw_arg2; 1875c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C prom_infop = (struct psb_info *)(long)(int)fw_arg3; 1885c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C 1895c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C nlm_prom_info = *prom_infop; 19077ae798f5b736dfdc692b86b393d9699052ac77aJayachandran C nlm_init_node(); 1915c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C 192571886b2a52395f030d439c6259663a033e11e6aJayachandran C /* Update reset entry point with CPU init code */ 193571886b2a52395f030d439c6259663a033e11e6aJayachandran C reset_vec = (void *)CKSEG1ADDR(RESET_VEC_PHYS); 194919f9abb3723f088290c62648b12fbfc7600d923Jayachandran C memset(reset_vec, 0, RESET_VEC_SIZE); 195571886b2a52395f030d439c6259663a033e11e6aJayachandran C memcpy(reset_vec, (void *)nlm_reset_entry, 196571886b2a52395f030d439c6259663a033e11e6aJayachandran C (nlm_reset_entry_end - nlm_reset_entry)); 197571886b2a52395f030d439c6259663a033e11e6aJayachandran C 1985c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C build_arcs_cmdline(argv); 1995c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C prom_add_memory(); 2005c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C 2015c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C#ifdef CONFIG_SMP 2022a37b1ae443f20470a789b12a45cbc249c9e50a6Jayachandran C for (i = 0; i < 32; i++) 2032a37b1ae443f20470a789b12a45cbc249c9e50a6Jayachandran C if (nlm_prom_info.online_cpu_map & (1 << i)) 2042a37b1ae443f20470a789b12a45cbc249c9e50a6Jayachandran C cpumask_set_cpu(i, &nlm_cpumask); 2052a37b1ae443f20470a789b12a45cbc249c9e50a6Jayachandran C nlm_wakeup_secondary_cpus(); 2065c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C register_smp_ops(&nlm_smp_ops); 2075c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C#endif 208ed21cfe207276e2d2883173399dd0380db372e18Ganesan Ramalingam xlr_board_info_setup(); 209ed21cfe207276e2d2883173399dd0380db372e18Ganesan Ramalingam xlr_percpu_fmn_init(); 2105c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C} 211