diff options
author | Jayachandran C <jchandra@broadcom.com> | 2012-10-31 16:01:39 +0400 |
---|---|---|
committer | John Crispin <blogic@openwrt.org> | 2012-11-09 14:37:19 +0400 |
commit | 77ae798f5b736dfdc692b86b393d9699052ac77a (patch) | |
tree | 040a68a1c544167364e4ca2b78e69179c397e4b2 /arch/mips/netlogic/xlp | |
parent | 2a37b1ae443f20470a789b12a45cbc249c9e50a6 (diff) | |
download | linux-77ae798f5b736dfdc692b86b393d9699052ac77a.tar.xz |
MIPS: Netlogic: Support for multi-chip configuration
Upto 4 Netlogic XLP SoCs can be connected over ICI links to form a
coherent multi-node system. Each SoC has its own set of on-chip
devices including PIC. To support this, add a per SoC stucture and
use it for the PIC and SYS block addresses instead of using global
variables.
Signed-off-by: Jayachandran C <jchandra@broadcom.com>
Patchwork: http://patchwork.linux-mips.org/patch/4469
Signed-off-by: John Crispin <blogic@openwrt.org>
Diffstat (limited to 'arch/mips/netlogic/xlp')
-rw-r--r-- | arch/mips/netlogic/xlp/nlm_hal.c | 29 | ||||
-rw-r--r-- | arch/mips/netlogic/xlp/setup.c | 17 | ||||
-rw-r--r-- | arch/mips/netlogic/xlp/wakeup.c | 22 |
3 files changed, 37 insertions, 31 deletions
diff --git a/arch/mips/netlogic/xlp/nlm_hal.c b/arch/mips/netlogic/xlp/nlm_hal.c index 6c65ac701912..d3a26e740acb 100644 --- a/arch/mips/netlogic/xlp/nlm_hal.c +++ b/arch/mips/netlogic/xlp/nlm_hal.c @@ -40,23 +40,23 @@ #include <asm/mipsregs.h> #include <asm/time.h> +#include <asm/netlogic/common.h> #include <asm/netlogic/haldefs.h> #include <asm/netlogic/xlp-hal/iomap.h> #include <asm/netlogic/xlp-hal/xlp.h> #include <asm/netlogic/xlp-hal/pic.h> #include <asm/netlogic/xlp-hal/sys.h> -/* These addresses are computed by the nlm_hal_init() */ -uint64_t nlm_io_base; -uint64_t nlm_sys_base; -uint64_t nlm_pic_base; - /* Main initialization */ -void nlm_hal_init(void) +void nlm_node_init(int node) { - nlm_io_base = CKSEG1ADDR(XLP_DEFAULT_IO_BASE); - nlm_sys_base = nlm_get_sys_regbase(0); /* node 0 */ - nlm_pic_base = nlm_get_pic_regbase(0); /* node 0 */ + struct nlm_soc_info *nodep; + + nodep = nlm_get_node(node); + nodep->sysbase = nlm_get_sys_regbase(node); + nodep->picbase = nlm_get_pic_regbase(node); + nodep->ebase = read_c0_ebase() & (~((1 << 12) - 1)); + spin_lock_init(&nodep->piclock); } int nlm_irq_to_irt(int irq) @@ -138,14 +138,15 @@ int nlm_irt_to_irq(int irt) } } -unsigned int nlm_get_core_frequency(int core) +unsigned int nlm_get_core_frequency(int node, int core) { unsigned int pll_divf, pll_divr, dfs_div, ext_div; unsigned int rstval, dfsval, denom; - uint64_t num; + uint64_t num, sysbase; - rstval = nlm_read_sys_reg(nlm_sys_base, SYS_POWER_ON_RESET_CFG); - dfsval = nlm_read_sys_reg(nlm_sys_base, SYS_CORE_DFS_DIV_VALUE); + sysbase = nlm_get_node(node)->sysbase; + rstval = nlm_read_sys_reg(sysbase, SYS_POWER_ON_RESET_CFG); + dfsval = nlm_read_sys_reg(sysbase, SYS_CORE_DFS_DIV_VALUE); pll_divf = ((rstval >> 10) & 0x7f) + 1; pll_divr = ((rstval >> 8) & 0x3) + 1; ext_div = ((rstval >> 30) & 0x3) + 1; @@ -159,5 +160,5 @@ unsigned int nlm_get_core_frequency(int core) unsigned int nlm_get_cpu_frequency(void) { - return nlm_get_core_frequency(0); + return nlm_get_core_frequency(0, 0); } diff --git a/arch/mips/netlogic/xlp/setup.c b/arch/mips/netlogic/xlp/setup.c index 9f8d360a246e..465b8d60463f 100644 --- a/arch/mips/netlogic/xlp/setup.c +++ b/arch/mips/netlogic/xlp/setup.c @@ -52,17 +52,17 @@ #include <asm/netlogic/xlp-hal/xlp.h> #include <asm/netlogic/xlp-hal/sys.h> -unsigned long nlm_common_ebase = 0x0; - -/* default to uniprocessor */ -uint32_t nlm_coremask = 1; +uint64_t nlm_io_base; +struct nlm_soc_info nlm_nodes[NLM_NR_NODES]; cpumask_t nlm_cpumask = CPU_MASK_CPU0; -int nlm_threads_per_core = 1; +unsigned int nlm_threads_per_core; extern u32 __dtb_start[]; static void nlm_linux_exit(void) { - nlm_write_sys_reg(nlm_sys_base, SYS_CHIP_RESET, 1); + uint64_t sysbase = nlm_get_node(0)->sysbase; + + nlm_write_sys_reg(sysbase, SYS_CHIP_RESET, 1); for ( ; ; ) cpu_wait(); } @@ -110,10 +110,9 @@ void xlp_mmu_init(void) void __init prom_init(void) { + nlm_io_base = CKSEG1ADDR(XLP_DEFAULT_IO_BASE); xlp_mmu_init(); - nlm_hal_init(); - - nlm_common_ebase = read_c0_ebase() & (~((1 << 12) - 1)); + nlm_node_init(0); #ifdef CONFIG_SMP cpumask_setall(&nlm_cpumask); diff --git a/arch/mips/netlogic/xlp/wakeup.c b/arch/mips/netlogic/xlp/wakeup.c index 88ce38d096f0..cb9010642ac3 100644 --- a/arch/mips/netlogic/xlp/wakeup.c +++ b/arch/mips/netlogic/xlp/wakeup.c @@ -79,32 +79,38 @@ static int xlp_wakeup_core(uint64_t sysbase, int core) static void xlp_enable_secondary_cores(const cpumask_t *wakeup_mask) { - uint64_t syspcibase, sysbase; + struct nlm_soc_info *nodep; + uint64_t syspcibase; uint32_t syscoremask; - int core, n; + int core, n, cpu; - for (n = 0; n < 4; n++) { + for (n = 0; n < NLM_NR_NODES; n++) { syspcibase = nlm_get_sys_pcibase(n); if (nlm_read_reg(syspcibase, 0) == 0xffffffff) break; /* read cores in reset from SYS and account for boot cpu */ - sysbase = nlm_get_sys_regbase(n); - syscoremask = nlm_read_sys_reg(sysbase, SYS_CPU_RESET); + nlm_node_init(n); + nodep = nlm_get_node(n); + syscoremask = nlm_read_sys_reg(nodep->sysbase, SYS_CPU_RESET); if (n == 0) syscoremask |= 1; - for (core = 0; core < 8; core++) { + for (core = 0; core < NLM_CORES_PER_NODE; core++) { /* see if the core exists */ if ((syscoremask & (1 << core)) == 0) continue; /* see if at least the first thread is enabled */ - if (!cpumask_test_cpu((n * 8 + core) * 4, wakeup_mask)) + cpu = (n * NLM_CORES_PER_NODE + core) + * NLM_THREADS_PER_CORE; + if (!cpumask_test_cpu(cpu, wakeup_mask)) continue; /* wake up the core */ - if (!xlp_wakeup_core(sysbase, core)) + if (xlp_wakeup_core(nodep->sysbase, core)) + nodep->coremask |= 1u << core; + else pr_err("Failed to enable core %d\n", core); } } |