linux/arch/sh/kernel/cpu/sh4/probe.c
<<
>>
Prefs
   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
  15void 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}
 261