summaryrefslogtreecommitdiffstats
path: root/arch/mips/netlogic/xlp
diff options
context:
space:
mode:
authorJayachandran C <jchandra@broadcom.com>2012-10-31 12:01:39 +0000
committerJohn Crispin <blogic@openwrt.org>2012-11-09 11:37:19 +0100
commit77ae798f5b736dfdc692b86b393d9699052ac77a (patch)
tree040a68a1c544167364e4ca2b78e69179c397e4b2 /arch/mips/netlogic/xlp
parent2a37b1ae443f20470a789b12a45cbc249c9e50a6 (diff)
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.c29
-rw-r--r--arch/mips/netlogic/xlp/setup.c17
-rw-r--r--arch/mips/netlogic/xlp/wakeup.c22
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 6c65ac70191..d3a26e740ac 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 9f8d360a246..465b8d60463 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 88ce38d096f..cb9010642ac 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);
}
}