// SPDX-License-Identifier: GPL-2.0
/*
* arch/sh/kernel/cpu/sh4/probe.c
*
* CPU Subtype Probing for SH-4.
*
* Copyright (C) 2001 - 2007 Paul Mundt
* Copyright (C) 2003 Richard Curnow
*/
#include <linux/init.h>
#include <linux/io.h>
#include <asm /processor.h>
#include <asm /cache.h>
void cpu_probe(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 = (__raw_readl(CCN_PVR) >> 8 ) & 0 xffffff;
prr = (__raw_readl(CCN_PRR) >> 4 ) & 0 xff;
cvr = (__raw_readl(CCN_CVR));
/*
* Setup some sane SH-4 defaults for the icache
*/
boot_cpu_data.icache.way_incr = (1 << 13 );
boot_cpu_data.icache.entry_shift = 5 ;
boot_cpu_data.icache.sets = 256 ;
boot_cpu_data.icache.ways = 1 ;
boot_cpu_data.icache.linesz = L1_CACHE_BYTES;
/*
* And again for the dcache ..
*/
boot_cpu_data.dcache.way_incr = (1 << 14 );
boot_cpu_data.dcache.entry_shift = 5 ;
boot_cpu_data.dcache.sets = 512 ;
boot_cpu_data.dcache.ways = 1 ;
boot_cpu_data.dcache.linesz = L1_CACHE_BYTES;
/* We don't know the chip cut */
boot_cpu_data.cut_major = boot_cpu_data.cut_minor = -1 ;
/*
* Setup some generic flags we can probe on SH-4A parts
*/
if (((pvr >> 16 ) & 0 xff) == 0 x10) {
boot_cpu_data.family = CPU_FAMILY_SH4A;
if ((cvr & 0 x10000000) == 0 ) {
boot_cpu_data.flags |= CPU_HAS_DSP;
boot_cpu_data.family = CPU_FAMILY_SH4AL_DSP;
}
boot_cpu_data.flags |= CPU_HAS_LLSC | CPU_HAS_PERF_COUNTER;
boot_cpu_data.cut_major = pvr & 0 x7f;
boot_cpu_data.icache.ways = 4 ;
boot_cpu_data.dcache.ways = 4 ;
} else {
/* And some SH-4 defaults.. */
boot_cpu_data.flags |= CPU_HAS_PTEA | CPU_HAS_FPU;
boot_cpu_data.family = CPU_FAMILY_SH4;
}
/* FPU detection works for almost everyone */
if ((cvr & 0 x20000000))
boot_cpu_data.flags |= CPU_HAS_FPU;
/* Mask off the upper chip ID */
pvr &= 0 xffff;
/*
* Probe the underlying processor version/revision and
* adjust cpu_data setup accordingly.
*/
switch (pvr) {
case 0 x205:
boot_cpu_data.type = CPU_SH7750;
boot_cpu_data.flags |= CPU_HAS_P2_FLUSH_BUG |
CPU_HAS_PERF_COUNTER;
break ;
case 0 x206:
boot_cpu_data.type = CPU_SH7750S;
boot_cpu_data.flags |= CPU_HAS_P2_FLUSH_BUG |
CPU_HAS_PERF_COUNTER;
break ;
case 0 x1100:
boot_cpu_data.type = CPU_SH7751;
break ;
case 0 x2001:
case 0 x2004:
boot_cpu_data.type = CPU_SH7770;
break ;
case 0 x2006:
case 0 x200A:
if (prr == 0 x61)
boot_cpu_data.type = CPU_SH7781;
else if (prr == 0 xa1)
boot_cpu_data.type = CPU_SH7763;
else
boot_cpu_data.type = CPU_SH7780;
break ;
case 0 x3000:
case 0 x3003:
case 0 x3009:
boot_cpu_data.type = CPU_SH7343;
break ;
case 0 x3004:
case 0 x3007:
boot_cpu_data.type = CPU_SH7785;
break ;
case 0 x4004:
case 0 x4005:
boot_cpu_data.type = CPU_SH7786;
boot_cpu_data.flags |= CPU_HAS_PTEAEX | CPU_HAS_L2_CACHE;
break ;
case 0 x3008:
switch (prr) {
case 0 x50:
case 0 x51:
boot_cpu_data.type = CPU_SH7723;
boot_cpu_data.flags |= CPU_HAS_L2_CACHE;
break ;
case 0 x70:
boot_cpu_data.type = CPU_SH7366;
break ;
case 0 xa0:
case 0 xa1:
boot_cpu_data.type = CPU_SH7722;
break ;
}
break ;
case 0 x300b:
switch (prr) {
case 0 x20:
boot_cpu_data.type = CPU_SH7724;
boot_cpu_data.flags |= CPU_HAS_L2_CACHE;
break ;
case 0 x10:
case 0 x11:
boot_cpu_data.type = CPU_SH7757;
break ;
case 0 xd0:
case 0 x40: /* yon-ten-go */
boot_cpu_data.type = CPU_SH7372;
break ;
case 0 xE0: /* 0x4E0 */
boot_cpu_data.type = CPU_SH7734; /* SH7733/SH7734 */
break ;
}
break ;
case 0 x4000: /* 1st cut */
case 0 x4001: /* 2nd cut */
boot_cpu_data.type = CPU_SHX3;
break ;
case 0 x700:
boot_cpu_data.type = CPU_SH4_501;
boot_cpu_data.flags &= ~CPU_HAS_FPU;
boot_cpu_data.icache.ways = 2 ;
boot_cpu_data.dcache.ways = 2 ;
break ;
case 0 x600:
boot_cpu_data.type = CPU_SH4_202;
boot_cpu_data.icache.ways = 2 ;
boot_cpu_data.dcache.ways = 2 ;
break ;
case 0 x500 ... 0 x501:
switch (prr) {
case 0 x10:
boot_cpu_data.type = CPU_SH7750R;
break ;
case 0 x11:
boot_cpu_data.type = CPU_SH7751R;
break ;
case 0 x50 ... 0 x5f:
boot_cpu_data.type = CPU_SH7760;
break ;
}
boot_cpu_data.icache.ways = 2 ;
boot_cpu_data.dcache.ways = 2 ;
break ;
}
/*
* On anything that's not a direct-mapped cache, look to the CVR
* for I/D-cache specifics.
*/
if (boot_cpu_data.icache.ways > 1 ) {
size = sizes[(cvr >> 20 ) & 0 xf];
boot_cpu_data.icache.way_incr = (size >> 1 );
boot_cpu_data.icache.sets = (size >> 6 );
}
/* And the rest of the D-cache */
if (boot_cpu_data.dcache.ways > 1 ) {
size = sizes[(cvr >> 16 ) & 0 xf];
boot_cpu_data.dcache.way_incr = (size >> 1 );
boot_cpu_data.dcache.sets = (size >> 6 );
}
/*
* SH-4A's have an optional PIPT L2.
*/
if (boot_cpu_data.flags & CPU_HAS_L2_CACHE) {
/*
* Verify that it really has something hooked up, this
* is the safety net for CPUs that have optional L2
* support yet do not implement it.
*/
if ((cvr & 0 xf) == 0 )
boot_cpu_data.flags &= ~CPU_HAS_L2_CACHE;
else {
/*
* Silicon and specifications have clearly never
* met..
*/
cvr ^= 0 xf;
/*
* Size calculation is much more sensible
* than it is for the L1.
*
* Sizes are 128KB, 256KB, 512KB, and 1MB.
*/
size = (cvr & 0 xf) << 17 ;
boot_cpu_data.scache.way_incr = (1 << 16 );
boot_cpu_data.scache.entry_shift = 5 ;
boot_cpu_data.scache.ways = 4 ;
boot_cpu_data.scache.linesz = L1_CACHE_BYTES;
boot_cpu_data.scache.entry_mask =
(boot_cpu_data.scache.way_incr -
boot_cpu_data.scache.linesz);
boot_cpu_data.scache.sets = size /
(boot_cpu_data.scache.linesz *
boot_cpu_data.scache.ways);
boot_cpu_data.scache.way_size =
(boot_cpu_data.scache.sets *
boot_cpu_data.scache.linesz);
}
}
}
Messung V0.5 in Prozent C=94 H=94 G=93
¤ Dauer der Verarbeitung: 0.8 Sekunden
(vorverarbeitet am 2026-06-08)
¤
*© Formatika GbR, Deutschland