int __init detect_cpu_and_cache_system(void)
{
- unsigned long pvr, prr, ccr, cvr;
+ unsigned long pvr, prr, cvr;
unsigned long size;
static unsigned long sizes[16] = {
/*
* Setup some sane SH-4 defaults for the icache
*/
- cpu_data->icache.way_shift = 13;
+ cpu_data->icache.way_incr = (1 << 13);
cpu_data->icache.entry_shift = 5;
cpu_data->icache.entry_mask = 0x1fe0;
cpu_data->icache.sets = 256;
/*
* And again for the dcache ..
*/
- cpu_data->dcache.way_shift = 14;
+ 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.linesz = L1_CACHE_BYTES;
/* Set the FPU flag, virtually all SH-4's have one */
- set_bit(CPU_HAS_FPU, &(cpu_data->flags));
+ cpu_data->flags |= CPU_HAS_FPU;
/*
* Probe the underlying processor version/revision and
switch (pvr) {
case 0x205:
cpu_data->type = CPU_SH7750;
- set_bit(CPU_HAS_P2_FLUSH_BUG, &(cpu_data->flags));
+ 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
*/
- set_bit(CPU_HAS_P2_FLUSH_BUG, &(cpu_data->flags));
+ cpu_data->flags |= CPU_HAS_P2_FLUSH_BUG;
break;
case 0x1100:
cpu_data->dcache.ways = 2;
/* No FPU on the SH4-500 series.. */
- clear_bit(CPU_HAS_FPU, &(cpu_data->flags));
+ cpu_data->flags &= ~CPU_HAS_FPU;
break;
case 0x600:
cpu_data->type = CPU_SH4_202;
* On anything that's not a direct-mapped cache, look to the CVR
* for I/D-cache specifics.
*/
- if (cpu_data->dcache.ways > 1) {
- jump_to_P2();
- ccr = ctrl_inl(CCR);
-
- /* Force EMODE */
- if (!(ccr & CCR_CACHE_EMODE)) {
- ccr |= CCR_CACHE_EMODE;
- ctrl_outl(ccr, CCR);
- }
-
- back_to_P1();
-
+ if (cpu_data->icache.ways > 1) {
size = sizes[(cvr >> 20) & 0xf];
- cpu_data->icache.way_shift = (size >> 1);
- cpu_data->icache.entry_mask = ((size >> 2) - (1 << 5));
- cpu_data->icache.sets = (size >> 6);
+ 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_shift = (size >> 1);
- cpu_data->dcache.entry_mask = ((size >> 2) - (1 << 5));
- cpu_data->dcache.sets = (size >> 6);
+ 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;
int i;
entry_offset = 1 << cpu_data->dcache.entry_shift;
- for (i = 0; i < cpu_data->dcache.ways; i++, start += (1 << cpu_data->dcache.way_shift)) {
+ for (i = 0; i < cpu_data->dcache.ways; i++, start += cpu_data->dcache.way_incr) {
for (addr = CACHE_OC_ADDRESS_ARRAY + start;
addr < CACHE_OC_ADDRESS_ARRAY + 4096 + start;
addr += entry_offset) {
local_irq_save(flags);
jump_to_P2();
- for(i = 0; i < cpu_data->icache.ways; i++, index += (1 << cpu_data->icache.way_shift))
+ for(i = 0; i < cpu_data->icache.ways; i++, index += cpu_data->icache.way_incr)
ctrl_outl(0, index); /* Clear out Valid-bit */
back_to_P1();
local_irq_restore(flags);
* SH7751, SH7751R, and ST40 have no restriction to handle cache.
* (While SH7750 must do that at P2 area.)
*/
- if (test_bit(CPU_HAS_P2_FLUSH_BUG, &(cpu_data->flags))) {
+ if ((cpu_data->flags & CPU_HAS_P2_FLUSH_BUG)
+ || start < CACHE_OC_ADDRESS_ARRAY) {
local_irq_save(flags);
- __flush_cache_4096(start | SH_CACHE_ASSOC, phys | 0x80000000, 0x20000000);
+ __flush_cache_4096(start | SH_CACHE_ASSOC, P1SEGADDR(phys), 0x20000000);
local_irq_restore(flags);
- } else if (start >= CACHE_OC_ADDRESS_ARRAY) {
- __flush_cache_4096(start | SH_CACHE_ASSOC, phys | 0x80000000, 0);
+ } else {
+ __flush_cache_4096(start | SH_CACHE_ASSOC, P1SEGADDR(phys), 0);
}
}