root/arch/sh/kernel/cpu/sh4/probe.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. cpu_probe

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * arch/sh/kernel/cpu/sh4/probe.c
   4  *
   5  * CPU Subtype Probing for SH-4.
   6  *
   7  * Copyright (C) 2001 - 2007  Paul Mundt
   8  * Copyright (C) 2003  Richard Curnow
   9  */
  10 #include <linux/init.h>
  11 #include <linux/io.h>
  12 #include <asm/processor.h>
  13 #include <asm/cache.h>
  14 
  15 void cpu_probe(void)
  16 {
  17         unsigned long pvr, prr, cvr;
  18         unsigned long size;
  19 
  20         static unsigned long sizes[16] = {
  21                 [1] = (1 << 12),
  22                 [2] = (1 << 13),
  23                 [4] = (1 << 14),
  24                 [8] = (1 << 15),
  25                 [9] = (1 << 16)
  26         };
  27 
  28         pvr = (__raw_readl(CCN_PVR) >> 8) & 0xffffff;
  29         prr = (__raw_readl(CCN_PRR) >> 4) & 0xff;
  30         cvr = (__raw_readl(CCN_CVR));
  31 
  32         /*
  33          * Setup some sane SH-4 defaults for the icache
  34          */
  35         boot_cpu_data.icache.way_incr           = (1 << 13);
  36         boot_cpu_data.icache.entry_shift        = 5;
  37         boot_cpu_data.icache.sets               = 256;
  38         boot_cpu_data.icache.ways               = 1;
  39         boot_cpu_data.icache.linesz             = L1_CACHE_BYTES;
  40 
  41         /*
  42          * And again for the dcache ..
  43          */
  44         boot_cpu_data.dcache.way_incr           = (1 << 14);
  45         boot_cpu_data.dcache.entry_shift        = 5;
  46         boot_cpu_data.dcache.sets               = 512;
  47         boot_cpu_data.dcache.ways               = 1;
  48         boot_cpu_data.dcache.linesz             = L1_CACHE_BYTES;
  49 
  50         /* We don't know the chip cut */
  51         boot_cpu_data.cut_major = boot_cpu_data.cut_minor = -1;
  52 
  53         /*
  54          * Setup some generic flags we can probe on SH-4A parts
  55          */
  56         if (((pvr >> 16) & 0xff) == 0x10) {
  57                 boot_cpu_data.family = CPU_FAMILY_SH4A;
  58 
  59                 if ((cvr & 0x10000000) == 0) {
  60                         boot_cpu_data.flags |= CPU_HAS_DSP;
  61                         boot_cpu_data.family = CPU_FAMILY_SH4AL_DSP;
  62                 }
  63 
  64                 boot_cpu_data.flags |= CPU_HAS_LLSC | CPU_HAS_PERF_COUNTER;
  65                 boot_cpu_data.cut_major = pvr & 0x7f;
  66 
  67                 boot_cpu_data.icache.ways = 4;
  68                 boot_cpu_data.dcache.ways = 4;
  69         } else {
  70                 /* And some SH-4 defaults.. */
  71                 boot_cpu_data.flags |= CPU_HAS_PTEA | CPU_HAS_FPU;
  72                 boot_cpu_data.family = CPU_FAMILY_SH4;
  73         }
  74 
  75         /* FPU detection works for almost everyone */
  76         if ((cvr & 0x20000000))
  77                 boot_cpu_data.flags |= CPU_HAS_FPU;
  78 
  79         /* Mask off the upper chip ID */
  80         pvr &= 0xffff;
  81 
  82         /*
  83          * Probe the underlying processor version/revision and
  84          * adjust cpu_data setup accordingly.
  85          */
  86         switch (pvr) {
  87         case 0x205:
  88                 boot_cpu_data.type = CPU_SH7750;
  89                 boot_cpu_data.flags |= CPU_HAS_P2_FLUSH_BUG |
  90                                        CPU_HAS_PERF_COUNTER;
  91                 break;
  92         case 0x206:
  93                 boot_cpu_data.type = CPU_SH7750S;
  94                 boot_cpu_data.flags |= CPU_HAS_P2_FLUSH_BUG |
  95                                        CPU_HAS_PERF_COUNTER;
  96                 break;
  97         case 0x1100:
  98                 boot_cpu_data.type = CPU_SH7751;
  99                 break;
 100         case 0x2001:
 101         case 0x2004:
 102                 boot_cpu_data.type = CPU_SH7770;
 103                 break;
 104         case 0x2006:
 105         case 0x200A:
 106                 if (prr == 0x61)
 107                         boot_cpu_data.type = CPU_SH7781;
 108                 else if (prr == 0xa1)
 109                         boot_cpu_data.type = CPU_SH7763;
 110                 else
 111                         boot_cpu_data.type = CPU_SH7780;
 112 
 113                 break;
 114         case 0x3000:
 115         case 0x3003:
 116         case 0x3009:
 117                 boot_cpu_data.type = CPU_SH7343;
 118                 break;
 119         case 0x3004:
 120         case 0x3007:
 121                 boot_cpu_data.type = CPU_SH7785;
 122                 break;
 123         case 0x4004:
 124         case 0x4005:
 125                 boot_cpu_data.type = CPU_SH7786;
 126                 boot_cpu_data.flags |= CPU_HAS_PTEAEX | CPU_HAS_L2_CACHE;
 127                 break;
 128         case 0x3008:
 129                 switch (prr) {
 130                 case 0x50:
 131                 case 0x51:
 132                         boot_cpu_data.type = CPU_SH7723;
 133                         boot_cpu_data.flags |= CPU_HAS_L2_CACHE;
 134                         break;
 135                 case 0x70:
 136                         boot_cpu_data.type = CPU_SH7366;
 137                         break;
 138                 case 0xa0:
 139                 case 0xa1:
 140                         boot_cpu_data.type = CPU_SH7722;
 141                         break;
 142                 }
 143                 break;
 144         case 0x300b:
 145                 switch (prr) {
 146                 case 0x20:
 147                         boot_cpu_data.type = CPU_SH7724;
 148                         boot_cpu_data.flags |= CPU_HAS_L2_CACHE;
 149                         break;
 150                 case 0x10:
 151                 case 0x11:
 152                         boot_cpu_data.type = CPU_SH7757;
 153                         break;
 154                 case 0xd0:
 155                 case 0x40: /* yon-ten-go */
 156                         boot_cpu_data.type = CPU_SH7372;
 157                         break;
 158                 case 0xE0: /* 0x4E0 */
 159                         boot_cpu_data.type = CPU_SH7734; /* SH7733/SH7734 */
 160                         break;
 161 
 162                 }
 163                 break;
 164         case 0x4000:    /* 1st cut */
 165         case 0x4001:    /* 2nd cut */
 166                 boot_cpu_data.type = CPU_SHX3;
 167                 break;
 168         case 0x700:
 169                 boot_cpu_data.type = CPU_SH4_501;
 170                 boot_cpu_data.flags &= ~CPU_HAS_FPU;
 171                 boot_cpu_data.icache.ways = 2;
 172                 boot_cpu_data.dcache.ways = 2;
 173                 break;
 174         case 0x600:
 175                 boot_cpu_data.type = CPU_SH4_202;
 176                 boot_cpu_data.icache.ways = 2;
 177                 boot_cpu_data.dcache.ways = 2;
 178                 break;
 179         case 0x500 ... 0x501:
 180                 switch (prr) {
 181                 case 0x10:
 182                         boot_cpu_data.type = CPU_SH7750R;
 183                         break;
 184                 case 0x11:
 185                         boot_cpu_data.type = CPU_SH7751R;
 186                         break;
 187                 case 0x50 ... 0x5f:
 188                         boot_cpu_data.type = CPU_SH7760;
 189                         break;
 190                 }
 191 
 192                 boot_cpu_data.icache.ways = 2;
 193                 boot_cpu_data.dcache.ways = 2;
 194 
 195                 break;
 196         }
 197 
 198         /*
 199          * On anything that's not a direct-mapped cache, look to the CVR
 200          * for I/D-cache specifics.
 201          */
 202         if (boot_cpu_data.icache.ways > 1) {
 203                 size = sizes[(cvr >> 20) & 0xf];
 204                 boot_cpu_data.icache.way_incr   = (size >> 1);
 205                 boot_cpu_data.icache.sets       = (size >> 6);
 206 
 207         }
 208 
 209         /* And the rest of the D-cache */
 210         if (boot_cpu_data.dcache.ways > 1) {
 211                 size = sizes[(cvr >> 16) & 0xf];
 212                 boot_cpu_data.dcache.way_incr   = (size >> 1);
 213                 boot_cpu_data.dcache.sets       = (size >> 6);
 214         }
 215 
 216         /*
 217          * SH-4A's have an optional PIPT L2.
 218          */
 219         if (boot_cpu_data.flags & CPU_HAS_L2_CACHE) {
 220                 /*
 221                  * Verify that it really has something hooked up, this
 222                  * is the safety net for CPUs that have optional L2
 223                  * support yet do not implement it.
 224                  */
 225                 if ((cvr & 0xf) == 0)
 226                         boot_cpu_data.flags &= ~CPU_HAS_L2_CACHE;
 227                 else {
 228                         /*
 229                          * Silicon and specifications have clearly never
 230                          * met..
 231                          */
 232                         cvr ^= 0xf;
 233 
 234                         /*
 235                          * Size calculation is much more sensible
 236                          * than it is for the L1.
 237                          *
 238                          * Sizes are 128KB, 256KB, 512KB, and 1MB.
 239                          */
 240                         size = (cvr & 0xf) << 17;
 241 
 242                         boot_cpu_data.scache.way_incr           = (1 << 16);
 243                         boot_cpu_data.scache.entry_shift        = 5;
 244                         boot_cpu_data.scache.ways               = 4;
 245                         boot_cpu_data.scache.linesz             = L1_CACHE_BYTES;
 246 
 247                         boot_cpu_data.scache.entry_mask =
 248                                 (boot_cpu_data.scache.way_incr -
 249                                  boot_cpu_data.scache.linesz);
 250 
 251                         boot_cpu_data.scache.sets       = size /
 252                                 (boot_cpu_data.scache.linesz *
 253                                  boot_cpu_data.scache.ways);
 254 
 255                         boot_cpu_data.scache.way_size   =
 256                                 (boot_cpu_data.scache.sets *
 257                                  boot_cpu_data.scache.linesz);
 258                 }
 259         }
 260 }

/* [<][>][^][v][top][bottom][index][help] */