]> git.hungrycats.org Git - linux/commitdiff
[PATCH] sh: Broken-out CPU subtype probing
authorPaul Mundt <paul.mundt@nokia.com>
Mon, 18 Oct 2004 16:00:48 +0000 (09:00 -0700)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Mon, 18 Oct 2004 16:00:48 +0000 (09:00 -0700)
Previously we could do subtype parsing and cache configuration in the same
location..  but with the introduction of things like the SH7705 where we use
SH-3 style probing with SH-4 style caches, this is no longer the case.  As
such, we move the probe code to a saner place.

Signed-off-by: Paul Mundt <paul.mundt@nokia.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
arch/sh/kernel/cpu/sh2/Makefile
arch/sh/kernel/cpu/sh2/probe.c [new file with mode: 0644]
arch/sh/kernel/cpu/sh3/Makefile
arch/sh/kernel/cpu/sh3/probe.c [new file with mode: 0644]
arch/sh/kernel/cpu/sh4/Makefile
arch/sh/kernel/cpu/sh4/probe.c [new file with mode: 0644]
arch/sh/mm/cache-sh2.c
arch/sh/mm/cache-sh3.c
arch/sh/mm/cache-sh4.c

index eb38f91d17261122781ed89ecf1da15b55896e0f..389353fba608f7aecf9a6e606f8f28892fbdeaf5 100644 (file)
@@ -2,3 +2,5 @@
 # Makefile for the Linux/SuperH SH-2 backends.
 #
 
+obj-y  := probe.o
+
diff --git a/arch/sh/kernel/cpu/sh2/probe.c b/arch/sh/kernel/cpu/sh2/probe.c
new file mode 100644 (file)
index 0000000..f17a2a0
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * arch/sh/kernel/cpu/sh2/probe.c
+ *
+ * CPU Subtype Probing for SH-2.
+ *
+ * Copyright (C) 2002 Paul Mundt
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+
+#include <linux/init.h>
+#include <asm/processor.h>
+#include <asm/cache.h>
+
+int __init detect_cpu_and_cache_system(void)
+{
+       /*
+        * For now, assume SH7604 .. fix this later.
+        */
+       cpu_data->type                  = CPU_SH7604;
+       cpu_data->dcache.ways           = 4;
+       cpu_data->dcache.way_shift      = 6;
+       cpu_data->dcache.sets           = 64;
+       cpu_data->dcache.entry_shift    = 4;
+       cpu_data->dcache.linesz         = L1_CACHE_BYTES;
+       cpu_data->dcache.flags          = 0;
+
+       /*
+        * SH-2 doesn't have separate caches
+        */
+       cpu_data->dcache.flags |= SH_CACHE_COMBINED;
+       cpu_data->icache = cpu_data->dcache;
+
+       return 0;
+}
+
index 196c5f07e118d826bd9092bc4cb8c39e92d8cf3d..a64532e4dc636f7690791898d13aa775b693e0f3 100644 (file)
@@ -2,5 +2,5 @@
 # Makefile for the Linux/SuperH SH-3 backends.
 #
 
-obj-y  := ex.o
+obj-y  := ex.o probe.o
 
diff --git a/arch/sh/kernel/cpu/sh3/probe.c b/arch/sh/kernel/cpu/sh3/probe.c
new file mode 100644 (file)
index 0000000..5cdc886
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * arch/sh/kernel/cpu/sh3/probe.c
+ *
+ * CPU Subtype Probing for SH-3.
+ *
+ * Copyright (C) 1999, 2000  Niibe Yutaka
+ * Copyright (C) 2002  Paul Mundt
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/init.h>
+#include <asm/processor.h>
+#include <asm/cache.h>
+#include <asm/io.h>
+
+int __init detect_cpu_and_cache_system(void)
+{
+       unsigned long addr0, addr1, data0, data1, data2, data3;
+
+       jump_to_P2();
+       /*
+        * Check if the entry shadows or not.
+        * When shadowed, it's 128-entry system.
+        * Otherwise, it's 256-entry system.
+        */
+       addr0 = CACHE_OC_ADDRESS_ARRAY + (3 << 12);
+       addr1 = CACHE_OC_ADDRESS_ARRAY + (1 << 12);
+
+       /* First, write back & invalidate */
+       data0  = ctrl_inl(addr0);
+       ctrl_outl(data0&~(SH_CACHE_VALID|SH_CACHE_UPDATED), addr0);
+       data1  = ctrl_inl(addr1);
+       ctrl_outl(data1&~(SH_CACHE_VALID|SH_CACHE_UPDATED), addr1);
+
+       /* Next, check if there's shadow or not */
+       data0 = ctrl_inl(addr0);
+       data0 ^= SH_CACHE_VALID;
+       ctrl_outl(data0, addr0);
+       data1 = ctrl_inl(addr1);
+       data2 = data1 ^ SH_CACHE_VALID;
+       ctrl_outl(data2, addr1);
+       data3 = ctrl_inl(addr0);
+
+       /* Lastly, invaliate them. */
+       ctrl_outl(data0&~SH_CACHE_VALID, addr0);
+       ctrl_outl(data2&~SH_CACHE_VALID, addr1);
+
+       back_to_P1();
+
+       cpu_data->dcache.ways           = 4;
+       cpu_data->dcache.entry_shift    = 4;
+       cpu_data->dcache.linesz         = L1_CACHE_BYTES;
+       cpu_data->dcache.flags          = 0;
+
+       /*
+        * 7709A/7729 has 16K cache (256-entry), while 7702 has only
+        * 2K(direct) 7702 is not supported (yet)
+        */
+       if (data0 == data1 && data2 == data3) { /* Shadow */
+               cpu_data->dcache.way_incr       = (1 << 11);
+               cpu_data->dcache.entry_mask     = 0x7f0;
+               cpu_data->dcache.sets           = 128;
+               cpu_data->type = CPU_SH7708;
+
+               cpu_data->flags |= CPU_HAS_MMU_PAGE_ASSOC;
+       } else {                                /* 7709A or 7729  */
+               cpu_data->dcache.way_incr       = (1 << 12);
+               cpu_data->dcache.entry_mask     = 0xff0;
+               cpu_data->dcache.sets           = 256;
+               cpu_data->type = CPU_SH7729;
+
+#if defined(CONFIG_CPU_SUBTYPE_SH7705)
+               cpu_data->type = CPU_SH7705;
+
+#if defined(CONFIG_SH7705_CACHE_32KB)
+               cpu_data->dcache.way_incr       = (1 << 13);
+               cpu_data->dcache.entry_mask     = 0x1ff0;
+               cpu_data->dcache.sets           = 512;
+               ctrl_outl(CCR_CACHE_32KB, CCR3);
+#else
+               ctrl_outl(CCR_CACHE_16KB, CCR3);
+#endif
+#endif
+       }
+
+       /*
+        * SH-3 doesn't have separate caches
+        */
+       cpu_data->dcache.flags |= SH_CACHE_COMBINED;
+       cpu_data->icache = cpu_data->dcache;
+
+       return 0;
+}
+
index fd59761431057f5021aa13a19c5baa4caa264289..ead1071eac738d0e87e2057da65c62cca4413828 100644 (file)
@@ -2,8 +2,9 @@
 # Makefile for the Linux/SuperH SH-4 backends.
 #
 
-obj-y  := fpu.o ex.o
+obj-y  := ex.o probe.o
 
+obj-$(CONFIG_SH_FPU)                    += fpu.o
 obj-$(CONFIG_CPU_SUBTYPE_ST40STB1)     += irq_intc2.o
 obj-$(CONFIG_SH_STORE_QUEUES)          += sq.o
 
diff --git a/arch/sh/kernel/cpu/sh4/probe.c b/arch/sh/kernel/cpu/sh4/probe.c
new file mode 100644 (file)
index 0000000..42427b7
--- /dev/null
@@ -0,0 +1,138 @@
+/*
+ * arch/sh/kernel/cpu/sh4/probe.c
+ *
+ * CPU Subtype Probing for SH-4.
+ *
+ * Copyright (C) 2001, 2002, 2003, 2004  Paul Mundt
+ * Copyright (C) 2003  Richard Curnow
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/init.h>
+#include <asm/processor.h>
+#include <asm/cache.h>
+#include <asm/io.h>
+
+int __init detect_cpu_and_cache_system(void)
+{
+       unsigned long pvr, prr, cvr;
+       unsigned long size;
+
+       static unsigned long sizes[16] = {
+               [1] = (1 << 12),
+               [2] = (1 << 13),
+               [4] = (1 << 14),
+               [8] = (1 << 15),
+               [9] = (1 << 16)
+       };
+
+       pvr = (ctrl_inl(CCN_PVR) >> 8) & 0xffff;
+       prr = (ctrl_inl(CCN_PRR) >> 4) & 0xff;
+       cvr = (ctrl_inl(CCN_CVR));
+
+       /*
+        * Setup some sane SH-4 defaults for the icache
+        */
+       cpu_data->icache.way_incr       = (1 << 13);
+       cpu_data->icache.entry_shift    = 5;
+       cpu_data->icache.entry_mask     = 0x1fe0;
+       cpu_data->icache.sets           = 256;
+       cpu_data->icache.ways           = 1;
+       cpu_data->icache.linesz         = L1_CACHE_BYTES;
+
+       /*
+        * And again for the dcache ..
+        */
+       cpu_data->dcache.way_incr       = (1 << 14);
+       cpu_data->dcache.entry_shift    = 5;
+       cpu_data->dcache.entry_mask     = 0x3fe0;
+       cpu_data->dcache.sets           = 512;
+       cpu_data->dcache.ways           = 1;
+       cpu_data->dcache.linesz         = L1_CACHE_BYTES;
+
+       /* Set the FPU flag, virtually all SH-4's have one */
+       cpu_data->flags |= CPU_HAS_FPU;
+
+       /*
+        * Probe the underlying processor version/revision and
+        * adjust cpu_data setup accordingly.
+        */
+       switch (pvr) {
+       case 0x205:
+               cpu_data->type = CPU_SH7750;
+               cpu_data->flags |= CPU_HAS_P2_FLUSH_BUG | CPU_HAS_PERF_COUNTER;
+               break;
+       case 0x206:
+               cpu_data->type = CPU_SH7750S;
+               cpu_data->flags |= CPU_HAS_P2_FLUSH_BUG | CPU_HAS_PERF_COUNTER;
+               break;
+       case 0x1100:
+               cpu_data->type = CPU_SH7751;
+               break;
+       case 0x2000:
+               cpu_data->type = CPU_SH73180;
+               cpu_data->icache.ways = 4;
+               cpu_data->dcache.ways = 4;
+               cpu_data->flags &= ~CPU_HAS_FPU;
+               break;
+       case 0x8000:
+               cpu_data->type = CPU_ST40RA;
+               break;
+       case 0x8100:
+               cpu_data->type = CPU_ST40GX1;
+               break;
+       case 0x700:
+               cpu_data->type = CPU_SH4_501;
+               cpu_data->icache.ways = 2;
+               cpu_data->dcache.ways = 2;
+
+               /* No FPU on the SH4-500 series.. */
+               cpu_data->flags &= ~CPU_HAS_FPU;
+               break;
+       case 0x600:
+               cpu_data->type = CPU_SH4_202;
+               cpu_data->icache.ways = 2;
+               cpu_data->dcache.ways = 2;
+               break;
+       case 0x500 ... 0x501:
+               switch (prr) {
+                   case 0x10: cpu_data->type = CPU_SH7750R; break;
+                   case 0x11: cpu_data->type = CPU_SH7751R; break;
+                   case 0x50: cpu_data->type = CPU_SH7760;  break;
+               }
+
+               cpu_data->icache.ways = 2;
+               cpu_data->dcache.ways = 2;
+
+               break;
+       default:
+               cpu_data->type = CPU_SH_NONE;
+               break;
+       }
+
+       /*
+        * On anything that's not a direct-mapped cache, look to the CVR
+        * for I/D-cache specifics.
+        */
+       if (cpu_data->icache.ways > 1) {
+               size = sizes[(cvr >> 20) & 0xf];
+               cpu_data->icache.way_incr       = (size >> 1);
+               cpu_data->icache.sets           = (size >> 6);
+               cpu_data->icache.entry_mask     =
+                       (cpu_data->icache.way_incr - (1 << 5));
+       }
+
+       if (cpu_data->dcache.ways > 1) {
+               size = sizes[(cvr >> 16) & 0xf];
+               cpu_data->dcache.way_incr       = (size >> 1);
+               cpu_data->dcache.sets           = (size >> 6);
+               cpu_data->dcache.entry_mask     =
+                       (cpu_data->dcache.way_incr - (1 << 5));
+       }
+
+       return 0;
+}
+
index ee5b452b19ac4742a3777a26892a8a1e49ca275c..2689cb24ea2b996aafe7a794af64e84380cf9323 100644 (file)
@@ -24,7 +24,7 @@
 unsigned long __get_oc_addr(unsigned long set, unsigned long way)
 {
        unsigned long ccr;
-       
+
        /*
         * On SH-2 the way bit isn't tracked in the address field
         * if we're doing address array access .. instead, we need
@@ -48,25 +48,3 @@ unsigned long __get_oc_addr(unsigned long set, unsigned long way)
        return CACHE_OC_ADDRESS_ARRAY | (set << cpu_data->dcache.entry_shift);
 }
 
-int __init detect_cpu_and_cache_system(void)
-{
-       /*
-        * For now, assume SH7604 .. fix this later.
-        */
-       cpu_data->type                  = CPU_SH7604;
-       cpu_data->dcache.ways           = 4;
-       cpu_data->dcache.way_shift      = 6;
-       cpu_data->dcache.sets           = 64;
-       cpu_data->dcache.entry_shift    = 4;
-       cpu_data->dcache.linesz         = L1_CACHE_BYTES;
-       cpu_data->dcache.flags          = 0;
-
-       /*
-        * SH-2 doesn't have separate caches
-        */
-       cpu_data->dcache.flags |= SH_CACHE_COMBINED;
-       cpu_data->icache = cpu_data->dcache;
-
-       return 0;
-}
-
index b03d5e441029c0a6ada0bfb42fe32e7f53450b8b..838731fc608dd6459178fc5fa5ecd9ef440b2629 100644 (file)
@@ -1,9 +1,10 @@
-/* $Id: cache-sh3.c,v 1.9 2004/05/02 01:46:30 sugioka Exp $
- *
- *  linux/arch/sh/mm/cache-sh3.c
+/*
+ * arch/sh/mm/cache-sh3.c
  *
  * Copyright (C) 1999, 2000  Niibe Yutaka
  * Copyright (C) 2002 Paul Mundt
+ *
+ * Released under the terms of the GNU GPL v2.0.
  */
 
 #include <linux/init.h>
 #include <asm/mmu_context.h>
 #include <asm/cacheflush.h>
 
-int __init detect_cpu_and_cache_system(void)
-{
-       unsigned long addr0, addr1, data0, data1, data2, data3;
-
-       jump_to_P2();
-       /*
-        * Check if the entry shadows or not.
-        * When shadowed, it's 128-entry system.
-        * Otherwise, it's 256-entry system.
-        */
-       addr0 = CACHE_OC_ADDRESS_ARRAY + (3 << 12);
-       addr1 = CACHE_OC_ADDRESS_ARRAY + (1 << 12);
-
-       /* First, write back & invalidate */
-       data0  = ctrl_inl(addr0);
-       ctrl_outl(data0&~(SH_CACHE_VALID|SH_CACHE_UPDATED), addr0);
-       data1  = ctrl_inl(addr1);
-       ctrl_outl(data1&~(SH_CACHE_VALID|SH_CACHE_UPDATED), addr1);
-
-       /* Next, check if there's shadow or not */
-       data0 = ctrl_inl(addr0);
-       data0 ^= SH_CACHE_VALID;
-       ctrl_outl(data0, addr0);
-       data1 = ctrl_inl(addr1);
-       data2 = data1 ^ SH_CACHE_VALID;
-       ctrl_outl(data2, addr1);
-       data3 = ctrl_inl(addr0);
-
-       /* Lastly, invaliate them. */
-       ctrl_outl(data0&~SH_CACHE_VALID, addr0);
-       ctrl_outl(data2&~SH_CACHE_VALID, addr1);
-
-       back_to_P1();
-
-       cpu_data->dcache.ways           = 4;
-       cpu_data->dcache.entry_shift    = 4;
-       cpu_data->dcache.linesz         = L1_CACHE_BYTES;
-       cpu_data->dcache.flags          = 0;
-
-       /*
-        * 7709A/7729 has 16K cache (256-entry), while 7702 has only
-        * 2K(direct) 7702 is not supported (yet)
-        */
-       if (data0 == data1 && data2 == data3) { /* Shadow */
-               cpu_data->dcache.way_incr       = (1 << 11);
-               cpu_data->dcache.entry_mask     = 0x7f0;
-               cpu_data->dcache.sets           = 128;
-               cpu_data->type = CPU_SH7708;
-
-               cpu_data->flags |= CPU_HAS_MMU_PAGE_ASSOC;
-       } else {                                /* 7709A or 7729  */
-               cpu_data->dcache.way_incr       = (1 << 12);
-               cpu_data->dcache.entry_mask     = 0xff0;
-               cpu_data->dcache.sets           = 256;
-               cpu_data->type = CPU_SH7729;
-       }
-
-       /*
-        * SH-3 doesn't have separate caches
-        */
-       cpu_data->dcache.flags |= SH_CACHE_COMBINED;
-       cpu_data->icache = cpu_data->dcache;
-
-       return 0;
-}
-
 /*
  * Write back the dirty D-caches, but not invalidate them.
  *
@@ -116,7 +51,7 @@ void __flush_wback_region(void *start, int size)
                        addr = addrstart | (v & cpu_data->dcache.entry_mask);
                        local_irq_save(flags);
                        data = ctrl_inl(addr);
-                       
+
                        if ((data & CACHE_PHYSADDR_MASK) ==
                            (p & CACHE_PHYSADDR_MASK)) {
                                data &= ~SH_CACHE_UPDATED;
index adb99d833d230d70c322a99c5a047b3ca702a16c..a877087d00dae2d6d4aaee392de08164aa8f0743 100644 (file)
@@ -1,10 +1,13 @@
-/* $Id: cache-sh4.c,v 1.26 2004/02/19 12:47:24 lethal Exp $
- *
- *  linux/arch/sh/mm/cache-sh4.c
+/*
+ * arch/sh/mm/cache-sh4.c
  *
  * Copyright (C) 1999, 2000, 2002  Niibe Yutaka
  * Copyright (C) 2001, 2002, 2003, 2004  Paul Mundt
  * Copyright (C) 2003  Richard Curnow
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
  */
 
 #include <linux/config.h>
@@ -28,126 +31,6 @@ static void __flush_cache_4096_all_ex(unsigned long start);
 extern void __flush_dcache_all(void);
 static void __flush_dcache_all_ex(void);
 
-int __init detect_cpu_and_cache_system(void)
-{
-       unsigned long pvr, prr, cvr;
-       unsigned long size;
-
-       static unsigned long sizes[16] = {
-               [1] = (1 << 12),
-               [2] = (1 << 13),
-               [4] = (1 << 14),
-               [8] = (1 << 15),
-               [9] = (1 << 16)
-       };
-
-       pvr = (ctrl_inl(CCN_PVR) >> 8) & 0xffff;
-       prr = (ctrl_inl(CCN_PRR) >> 4) & 0xff;
-       cvr = (ctrl_inl(CCN_CVR));
-
-       /*
-        * Setup some sane SH-4 defaults for the icache
-        */
-       cpu_data->icache.way_incr       = (1 << 13);
-       cpu_data->icache.entry_shift    = 5;
-       cpu_data->icache.entry_mask     = 0x1fe0;
-       cpu_data->icache.sets           = 256;
-       cpu_data->icache.ways           = 1;
-       cpu_data->icache.linesz         = L1_CACHE_BYTES;
-
-       /*
-        * And again for the dcache ..
-        */
-       cpu_data->dcache.way_incr       = (1 << 14);
-       cpu_data->dcache.entry_shift    = 5;
-       cpu_data->dcache.entry_mask     = 0x3fe0;
-       cpu_data->dcache.sets           = 512;
-       cpu_data->dcache.ways           = 1;
-       cpu_data->dcache.linesz         = L1_CACHE_BYTES;
-
-       /* Set the FPU flag, virtually all SH-4's have one */
-       cpu_data->flags |= CPU_HAS_FPU;
-
-       /*
-        * Probe the underlying processor version/revision and
-        * adjust cpu_data setup accordingly.
-        */
-       switch (pvr) {
-       case 0x205:
-               cpu_data->type = CPU_SH7750;
-               cpu_data->flags |= CPU_HAS_P2_FLUSH_BUG;
-               break;
-       case 0x206:
-               cpu_data->type = CPU_SH7750S;
-
-               /* 
-                * FIXME: This is needed for 7750, but do we need it for the
-                * 7750S too? For now, assume we do.. -- PFM
-                */
-               cpu_data->flags |= CPU_HAS_P2_FLUSH_BUG;
-
-               break;
-       case 0x1100:
-               cpu_data->type = CPU_SH7751;
-               break;
-       case 0x8000:
-               cpu_data->type = CPU_ST40RA;
-               break;
-       case 0x8100:
-               cpu_data->type = CPU_ST40GX1;
-               break;
-       case 0x700:
-               cpu_data->type = CPU_SH4_501;
-               cpu_data->icache.ways = 2;
-               cpu_data->dcache.ways = 2;
-
-               /* No FPU on the SH4-500 series.. */
-               cpu_data->flags &= ~CPU_HAS_FPU;
-               break;
-       case 0x600:
-               cpu_data->type = CPU_SH4_202;
-               cpu_data->icache.ways = 2;
-               cpu_data->dcache.ways = 2;
-               break;
-       case 0x500 ... 0x501:
-               switch (prr) {
-                   case 0x10: cpu_data->type = CPU_SH7750R; break;
-                   case 0x11: cpu_data->type = CPU_SH7751R; break;
-                   case 0x50: cpu_data->type = CPU_SH7760;  break;
-               }
-
-               cpu_data->icache.ways = 2;
-               cpu_data->dcache.ways = 2;
-
-               break;
-       default:
-               cpu_data->type = CPU_SH_NONE;
-               break;
-       }
-
-       /*
-        * On anything that's not a direct-mapped cache, look to the CVR
-        * for I/D-cache specifics.
-        */
-       if (cpu_data->icache.ways > 1) {
-               size = sizes[(cvr >> 20) & 0xf];
-               cpu_data->icache.way_incr       = size / cpu_data->icache.ways;
-               cpu_data->icache.sets           = (size >> 6);
-               cpu_data->icache.entry_mask     =
-                       ((size / cpu_data->icache.ways) - (1 << 5));
-       }
-
-       if (cpu_data->dcache.ways > 1) {
-               size = sizes[(cvr >> 16) & 0xf];
-               cpu_data->dcache.way_incr       = size / cpu_data->dcache.ways;
-               cpu_data->dcache.sets           = (size >> 6);
-               cpu_data->dcache.entry_mask     =
-                       ((size / cpu_data->dcache.ways) - (1 << 5));
-       }
-
-       return 0;
-}
-
 /*
  * SH-4 has virtually indexed and physically tagged cache.
  */