MIPS: Loongson-3: Introduce CONFIG_LOONGSON3_ENHANCEMENT
authorHuacai Chen <chenhc@lemote.com>
Thu, 3 Mar 2016 01:45:13 +0000 (09:45 +0800)
committerRalf Baechle <ralf@linux-mips.org>
Fri, 13 May 2016 12:02:15 +0000 (14:02 +0200)
New Loongson 3 CPU (since Loongson-3A R2, as opposed to Loongson-3A R1,
Loongson-3B R1 and Loongson-3B R2) has many enhancements, such as FTLB,
L1-VCache, EI/DI/Wait/Prefetch instruction, DSP/DSPv2 ASE, User Local
register, Read-Inhibit/Execute-Inhibit, SFB (Store Fill Buffer), Fast
TLB refill support, etc.

This patch introduce a config option, CONFIG_LOONGSON3_ENHANCEMENT, to
enable those enhancements which are not probed at run time. If you want
a generic kernel to run on all Loongson 3 machines, please say 'N'
here. If you want a high-performance kernel to run on new Loongson 3
machines only, please say 'Y' here.

Some additional explanations:
1) SFB locates between core and L1 cache, it causes memory access out
   of order, so writel/outl (and other similar functions) need a I/O
   reorder barrier.
2) Loongson 3 has a bug that di instruction can not save the irqflag,
   so arch_local_irq_save() is modified. Since CPU_MIPSR2 is selected
   by CONFIG_LOONGSON3_ENHANCEMENT, generic kernel doesn't use ei/di
   at all.
3) CPU_HAS_PREFETCH is selected by CONFIG_LOONGSON3_ENHANCEMENT, so
   MIPS_CPU_PREFETCH (used by uasm) probing is also put in this patch.

Signed-off-by: Huacai Chen <chenhc@lemote.com>
Cc: Aurelien Jarno <aurelien@aurel32.net>
Cc: Steven J . Hill <sjhill@realitydiluted.com>
Cc: Fuxin Zhang <zhangfx@lemote.com>
Cc: Zhangjin Wu <wuzhangjin@gmail.com>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/12755/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
arch/mips/Kconfig
arch/mips/include/asm/hazards.h
arch/mips/include/asm/io.h
arch/mips/include/asm/irqflags.h
arch/mips/include/asm/mach-loongson64/kernel-entry-init.h
arch/mips/mm/c-r4k.c
arch/mips/mm/page.c

index adcc97ea4392d2cb8c348976b98bc6cb7ef759a0..d5c3621f0dd1be1b66348128b411c9ef8259c249 100644 (file)
@@ -1360,6 +1360,24 @@ config CPU_LOONGSON3
                The Loongson 3 processor implements the MIPS64R2 instruction
                set with many extensions.
 
+config LOONGSON3_ENHANCEMENT
+       bool "New Loongson 3 CPU Enhancements"
+       default n
+       select CPU_MIPSR2
+       select CPU_HAS_PREFETCH
+       depends on CPU_LOONGSON3
+       help
+         New Loongson 3 CPU (since Loongson-3A R2, as opposed to Loongson-3A
+         R1, Loongson-3B R1 and Loongson-3B R2) has many enhancements, such as
+         FTLB, L1-VCache, EI/DI/Wait/Prefetch instruction, DSP/DSPv2 ASE, User
+         Local register, Read-Inhibit/Execute-Inhibit, SFB (Store Fill Buffer),
+         Fast TLB refill support, etc.
+
+         This option enable those enhancements which are not probed at run
+         time. If you want a generic kernel to run on all Loongson 3 machines,
+         please say 'N' here. If you want a high-performance kernel to run on
+         new Loongson 3 machines only, please say 'Y' here.
+
 config CPU_LOONGSON2E
        bool "Loongson 2E"
        depends on SYS_HAS_CPU_LOONGSON2E
index 7b99efd310748dbfe12c29459ffdd5e4137a2bf8..dbb1eb6e284f1e67880fadee3c8aed696164c31d 100644 (file)
@@ -22,7 +22,8 @@
 /*
  * TLB hazards
  */
-#if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6) && !defined(CONFIG_CPU_CAVIUM_OCTEON)
+#if (defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6)) && \
+       !defined(CONFIG_CPU_CAVIUM_OCTEON) && !defined(CONFIG_LOONGSON3_ENHANCEMENT)
 
 /*
  * MIPSR2 defines ehb for hazard avoidance
@@ -155,8 +156,8 @@ do {                                                                        \
 } while (0)
 
 #elif defined(CONFIG_MIPS_ALCHEMY) || defined(CONFIG_CPU_CAVIUM_OCTEON) || \
-       defined(CONFIG_CPU_LOONGSON2) || defined(CONFIG_CPU_R10000) || \
-       defined(CONFIG_CPU_R5500) || defined(CONFIG_CPU_XLR)
+       defined(CONFIG_CPU_LOONGSON2) || defined(CONFIG_LOONGSON3_ENHANCEMENT) || \
+       defined(CONFIG_CPU_R10000) || defined(CONFIG_CPU_R5500) || defined(CONFIG_CPU_XLR)
 
 /*
  * R10000 rocks - all hazards handled in hardware, so this becomes a nobrainer.
index 2b4dc7ad53b8a32bc139dd33d15cb5bb533f8d85..ecabc00c1e665ae237faf60a10f07599d04a65c3 100644 (file)
@@ -304,10 +304,10 @@ static inline void iounmap(const volatile void __iomem *addr)
 #undef __IS_KSEG1
 }
 
-#ifdef CONFIG_CPU_CAVIUM_OCTEON
-#define war_octeon_io_reorder_wmb()            wmb()
+#if defined(CONFIG_CPU_CAVIUM_OCTEON) || defined(CONFIG_LOONGSON3_ENHANCEMENT)
+#define war_io_reorder_wmb()           wmb()
 #else
-#define war_octeon_io_reorder_wmb()            do { } while (0)
+#define war_io_reorder_wmb()           do { } while (0)
 #endif
 
 #define __BUILD_MEMORY_SINGLE(pfx, bwlq, type, irq)                    \
@@ -318,7 +318,7 @@ static inline void pfx##write##bwlq(type val,                               \
        volatile type *__mem;                                           \
        type __val;                                                     \
                                                                        \
-       war_octeon_io_reorder_wmb();                                    \
+       war_io_reorder_wmb();                                   \
                                                                        \
        __mem = (void *)__swizzle_addr_##bwlq((unsigned long)(mem));    \
                                                                        \
@@ -387,7 +387,7 @@ static inline void pfx##out##bwlq##p(type val, unsigned long port)  \
        volatile type *__addr;                                          \
        type __val;                                                     \
                                                                        \
-       war_octeon_io_reorder_wmb();                                    \
+       war_io_reorder_wmb();                                   \
                                                                        \
        __addr = (void *)__swizzle_addr_##bwlq(mips_io_port_base + port); \
                                                                        \
index 65c351e328cc932af4aedca946ee19f9bd43f8c3..9d3610be2323a1ae885320ffe81cd3577e327872 100644 (file)
@@ -41,7 +41,12 @@ static inline unsigned long arch_local_irq_save(void)
        "       .set    push                                            \n"
        "       .set    reorder                                         \n"
        "       .set    noat                                            \n"
+#if defined(CONFIG_CPU_LOONGSON3)
+       "       mfc0    %[flags], $12                                   \n"
+       "       di                                                      \n"
+#else
        "       di      %[flags]                                        \n"
+#endif
        "       andi    %[flags], 1                                     \n"
        "       " __stringify(__irq_disable_hazard) "                   \n"
        "       .set    pop                                             \n"
index da83482ff0b97cfa6c80fcbc12e7bc04aed7dfba..8393bc548987d782b9f590b0a9ffecda9fabc61c 100644 (file)
        mfc0    t0, $5, 1
        or      t0, (0x1 << 29)
        mtc0    t0, $5, 1
+#ifdef CONFIG_LOONGSON3_ENHANCEMENT
+       /* Enable STFill Buffer */
+       mfc0    t0, $16, 6
+       or      t0, 0x100
+       mtc0    t0, $16, 6
+#endif
        _ehb
        .set    pop
 #endif
        mfc0    t0, $5, 1
        or      t0, (0x1 << 29)
        mtc0    t0, $5, 1
+#ifdef CONFIG_LOONGSON3_ENHANCEMENT
+       /* Enable STFill Buffer */
+       mfc0    t0, $16, 6
+       or      t0, 0x100
+       mtc0    t0, $16, 6
+#endif
        _ehb
        .set    pop
 #endif
index 3415d3e2a63bddcba9c87ffdb43bfaad817e4183..d73b304cfe8a218e0c288923467046a5bf7ed26f 100644 (file)
@@ -1161,6 +1161,8 @@ static void probe_pcache(void)
                                          c->dcache.ways *
                                          c->dcache.linesz;
                c->dcache.waybit = 0;
+               if ((prid & PRID_REV_MASK) >= PRID_REV_LOONGSON3A_R2)
+                       c->options |= MIPS_CPU_PREFETCH;
                break;
 
        case CPU_CAVIUM_OCTEON3:
index 885d73ffd6fb470ff237916784ef283c19b5c7eb..c41953ca6605ca347db0bbe71689fb791ef51410 100644 (file)
@@ -188,6 +188,15 @@ static void set_prefetch_parameters(void)
                        }
                        break;
 
+               case CPU_LOONGSON3:
+                       /* Loongson-3 only support the Pref_Load/Pref_Store. */
+                       pref_bias_clear_store = 128;
+                       pref_bias_copy_load = 128;
+                       pref_bias_copy_store = 128;
+                       pref_src_mode = Pref_Load;
+                       pref_dst_mode = Pref_Store;
+                       break;
+
                default:
                        pref_bias_clear_store = 128;
                        pref_bias_copy_load = 256;