diff options
author | Jayachandran C <jchandra@broadcom.com> | 2013-12-21 16:52:23 +0530 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2014-01-24 22:39:48 +0100 |
commit | 861c056953dc4354414881a5e1d382297ef4ea53 (patch) | |
tree | 9bfdf545e1335f0dbf41bfd081bfebb72f759460 /arch/mips/netlogic | |
parent | d150cef4e8cc723d90226e503ef6aff2ca9fc57c (diff) |
MIPS: Netlogic: SYS block updates of XLP9XX
Add the SYS block registers for XLP9XX, most of them have changed.
The wakeup sequence has been updated to set the coherent mode from
the main thread rather than the woken up thread.
Signed-off-by: Jayachandran C <jchandra@broadcom.com>
Signed-off-by: John Crispin <blogic@openwrt.org>
Patchwork: http://patchwork.linux-mips.org/patch/6280/
Diffstat (limited to 'arch/mips/netlogic')
-rw-r--r-- | arch/mips/netlogic/common/reset.S | 8 | ||||
-rw-r--r-- | arch/mips/netlogic/xlp/nlm_hal.c | 5 | ||||
-rw-r--r-- | arch/mips/netlogic/xlp/setup.c | 5 | ||||
-rw-r--r-- | arch/mips/netlogic/xlp/wakeup.c | 74 |
4 files changed, 67 insertions, 25 deletions
diff --git a/arch/mips/netlogic/common/reset.S b/arch/mips/netlogic/common/reset.S index 57eb7a141fbf..dfbf94d4df22 100644 --- a/arch/mips/netlogic/common/reset.S +++ b/arch/mips/netlogic/common/reset.S @@ -159,6 +159,13 @@ FEXPORT(nlm_reset_entry) nop 1: /* Entry point on core wakeup */ + mfc0 t0, CP0_EBASE, 0 /* processor ID */ + andi t0, 0xff00 + li t1, 0x1500 /* XLP 9xx */ + beq t0, t1, 2f /* does not need to set coherent */ + nop + + /* set bit in SYS coherent register for the core */ mfc0 t0, CP0_EBASE, 1 mfc0 t1, CP0_EBASE, 1 srl t1, 5 @@ -180,6 +187,7 @@ FEXPORT(nlm_reset_entry) lw t1, 0(t2) sync +2: /* Configure LSU on Non-0 Cores. */ xlp_config_lsu /* FALL THROUGH */ diff --git a/arch/mips/netlogic/xlp/nlm_hal.c b/arch/mips/netlogic/xlp/nlm_hal.c index 2d31cf1137fb..61f325d06e95 100644 --- a/arch/mips/netlogic/xlp/nlm_hal.c +++ b/arch/mips/netlogic/xlp/nlm_hal.c @@ -174,7 +174,10 @@ unsigned int nlm_get_core_frequency(int node, int core) uint64_t num, sysbase; sysbase = nlm_get_node(node)->sysbase; - rstval = nlm_read_sys_reg(sysbase, SYS_POWER_ON_RESET_CFG); + if (cpu_is_xlp9xx()) + rstval = nlm_read_sys_reg(sysbase, SYS_9XX_POWER_ON_RESET_CFG); + else + rstval = nlm_read_sys_reg(sysbase, SYS_POWER_ON_RESET_CFG); if (cpu_is_xlpii()) { num = 1000000ULL * (400 * 3 + 100 * (rstval >> 26)); denom = 3; diff --git a/arch/mips/netlogic/xlp/setup.c b/arch/mips/netlogic/xlp/setup.c index e92adec8a63b..310d88a82abe 100644 --- a/arch/mips/netlogic/xlp/setup.c +++ b/arch/mips/netlogic/xlp/setup.c @@ -56,7 +56,10 @@ 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(); } diff --git a/arch/mips/netlogic/xlp/wakeup.c b/arch/mips/netlogic/xlp/wakeup.c index f11035b1ad11..a5d6647e5fe8 100644 --- a/arch/mips/netlogic/xlp/wakeup.c +++ b/arch/mips/netlogic/xlp/wakeup.c @@ -54,7 +54,7 @@ static int xlp_wakeup_core(uint64_t sysbase, int node, int core) { uint32_t coremask, value; - int count; + int count, resetreg; coremask = (1 << core); @@ -65,12 +65,24 @@ static int xlp_wakeup_core(uint64_t sysbase, int node, int core) nlm_write_sys_reg(sysbase, SYS_CORE_DFS_DIS_CTRL, value); } + /* On 9XX, mark coherent first */ + if (cpu_is_xlp9xx()) { + value = nlm_read_sys_reg(sysbase, SYS_9XX_CPU_NONCOHERENT_MODE); + value &= ~coremask; + nlm_write_sys_reg(sysbase, SYS_9XX_CPU_NONCOHERENT_MODE, value); + } + /* Remove CPU Reset */ - value = nlm_read_sys_reg(sysbase, SYS_CPU_RESET); + resetreg = cpu_is_xlp9xx() ? SYS_9XX_CPU_RESET : SYS_CPU_RESET; + value = nlm_read_sys_reg(sysbase, resetreg); value &= ~coremask; - nlm_write_sys_reg(sysbase, SYS_CPU_RESET, value); + nlm_write_sys_reg(sysbase, resetreg, value); + + /* We are done on 9XX */ + if (cpu_is_xlp9xx()) + return 1; - /* Poll for CPU to mark itself coherent */ + /* Poll for CPU to mark itself coherent on other type of XLP */ count = 100000; do { value = nlm_read_sys_reg(sysbase, SYS_CPU_NONCOHERENT_MODE); @@ -98,33 +110,48 @@ static int wait_for_cpus(int cpu, int bootcpu) static void xlp_enable_secondary_cores(const cpumask_t *wakeup_mask) { struct nlm_soc_info *nodep; - uint64_t syspcibase; + uint64_t syspcibase, fusebase; uint32_t syscoremask, mask, fusemask; int core, n, cpu; for (n = 0; n < NLM_NR_NODES; n++) { - syspcibase = nlm_get_sys_pcibase(n); - if (nlm_read_reg(syspcibase, 0) == 0xffffffff) - break; + if (n != 0) { + /* check if node exists and is online */ + if (cpu_is_xlp9xx()) { + int b = xlp9xx_get_socbus(n); + pr_info("Node %d SoC PCI bus %d.\n", n, b); + if (b == 0) + break; + } else { + syspcibase = nlm_get_sys_pcibase(n); + if (nlm_read_reg(syspcibase, 0) == 0xffffffff) + break; + } + nlm_node_init(n); + } /* read cores in reset from SYS */ - if (n != 0) - nlm_node_init(n); nodep = nlm_get_node(n); - fusemask = nlm_read_sys_reg(nodep->sysbase, - SYS_EFUSE_DEVICE_CFG_STATUS0); - switch (read_c0_prid() & 0xff00) { - case PRID_IMP_NETLOGIC_XLP3XX: - mask = 0xf; - break; - case PRID_IMP_NETLOGIC_XLP2XX: - mask = 0x3; - break; - case PRID_IMP_NETLOGIC_XLP8XX: - default: - mask = 0xff; - break; + if (cpu_is_xlp9xx()) { + fusebase = nlm_get_fuse_regbase(n); + fusemask = nlm_read_reg(fusebase, FUSE_9XX_DEVCFG6); + mask = 0xfffff; + } else { + fusemask = nlm_read_sys_reg(nodep->sysbase, + SYS_EFUSE_DEVICE_CFG_STATUS0); + switch (read_c0_prid() & 0xff00) { + case PRID_IMP_NETLOGIC_XLP3XX: + mask = 0xf; + break; + case PRID_IMP_NETLOGIC_XLP2XX: + mask = 0x3; + break; + case PRID_IMP_NETLOGIC_XLP8XX: + default: + mask = 0xff; + break; + } } /* @@ -137,6 +164,7 @@ static void xlp_enable_secondary_cores(const cpumask_t *wakeup_mask) if (n == 0) nodep->coremask = 1; + pr_info("Node %d - SYS/FUSE coremask %x\n", n, syscoremask); for (core = 0; core < NLM_CORES_PER_NODE; core++) { /* we will be on node 0 core 0 */ if (n == 0 && core == 0) |