]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/commitdiff
MIPS: Netlogic: SYS block updates of XLP9XX
authorJayachandran C <jchandra@broadcom.com>
Sat, 21 Dec 2013 11:22:23 +0000 (16:52 +0530)
committerRalf Baechle <ralf@linux-mips.org>
Fri, 24 Jan 2014 21:39:48 +0000 (22:39 +0100)
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/

arch/mips/include/asm/netlogic/xlp-hal/sys.h
arch/mips/netlogic/common/reset.S
arch/mips/netlogic/xlp/nlm_hal.c
arch/mips/netlogic/xlp/setup.c
arch/mips/netlogic/xlp/wakeup.c

index fcf2833c16ca9d42c5119b3250cba8b20452d09e..d9b107ffca933ca525235321200f63f872a1d8c3 100644 (file)
 #define SYS_SYS_PLL_MEM_REQ                    0x2a3
 #define SYS_PLL_MEM_STAT                       0x2a4
 
+/* Registers changed on 9XX */
+#define SYS_9XX_POWER_ON_RESET_CFG             0x00
+#define SYS_9XX_CHIP_RESET                     0x01
+#define SYS_9XX_CPU_RESET                      0x02
+#define SYS_9XX_CPU_NONCOHERENT_MODE           0x03
+
+/* XLP 9XX fuse block registers */
+#define FUSE_9XX_DEVCFG6                       0xc6
+
 #ifndef __ASSEMBLY__
 
 #define nlm_read_sys_reg(b, r)         nlm_read_reg(b, r)
 #define nlm_write_sys_reg(b, r, v)     nlm_write_reg(b, r, v)
-#define nlm_get_sys_pcibase(node) nlm_pcicfg_base(XLP_IO_SYS_OFFSET(node))
+#define nlm_get_sys_pcibase(node)      nlm_pcicfg_base(cpu_is_xlp9xx() ? \
+               XLP9XX_IO_SYS_OFFSET(node) : XLP_IO_SYS_OFFSET(node))
 #define nlm_get_sys_regbase(node) (nlm_get_sys_pcibase(node) + XLP_IO_PCI_HDRSZ)
 
+/* XLP9XX fuse block */
+#define nlm_get_fuse_pcibase(node)     \
+                       nlm_pcicfg_base(XLP9XX_IO_FUSE_OFFSET(node))
+#define nlm_get_fuse_regbase(node)     \
+                       (nlm_get_fuse_pcibase(node) + XLP_IO_PCI_HDRSZ)
+
 unsigned int nlm_get_pic_frequency(int node);
 #endif
 #endif
index 57eb7a141fbf31b3276decd3dc98f48e4a359bf2..dfbf94d4df2256ab6f3f7ddaa24714e3085fb751 100644 (file)
@@ -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 */
index 2d31cf1137fbf27ba3d8dd865f43416f2da88ce4..61f325d06e95c0a08258dcb85a2180ab2ae3c96c 100644 (file)
@@ -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;
index e92adec8a63b3ec7e5313cb56040fcf896cecb95..310d88a82abe8ac06c3dac793c0bdc32f54e1c13 100644 (file)
@@ -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();
 }
index f11035b1ad117933f5998c1b1abce80f287bd3ae..a5d6647e5fe8030f627f885483036ffb2a6bea1d 100644 (file)
@@ -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)