// 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 - 4 A 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 - 4 A ' 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 128 KB , 256 KB , 512 KB , and 1 MB .
*/
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=93 H=96 G=94
¤ Dauer der Verarbeitung: 0.13 Sekunden
(vorverarbeitet am 2026-10-04)
¤
*© Formatika GbR, Deutschland