Blame view

arch/mips/mm/sc-mips.c 3.29 KB
9318c51ac   Chris Dearman   [MIPS] MIPS32/MIP...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
  /*
   * Copyright (C) 2006 Chris Dearman (chris@mips.com),
   */
  #include <linux/init.h>
  #include <linux/kernel.h>
  #include <linux/sched.h>
  #include <linux/mm.h>
  
  #include <asm/mipsregs.h>
  #include <asm/bcache.h>
  #include <asm/cacheops.h>
  #include <asm/page.h>
  #include <asm/pgtable.h>
  #include <asm/system.h>
  #include <asm/mmu_context.h>
  #include <asm/r4kcache.h>
  
  /*
   * MIPS32/MIPS64 L2 cache handling
   */
  
  /*
   * Writeback and invalidate the secondary cache before DMA.
   */
  static void mips_sc_wback_inv(unsigned long addr, unsigned long size)
  {
a2c2bc4b2   Atsushi Nemoto   [MIPS] MIPS32/MIP...
27
  	blast_scache_range(addr, addr + size);
9318c51ac   Chris Dearman   [MIPS] MIPS32/MIP...
28
29
30
31
32
33
34
  }
  
  /*
   * Invalidate the secondary cache before DMA.
   */
  static void mips_sc_inv(unsigned long addr, unsigned long size)
  {
96983ffef   Kevin Cernekee   MIPS: MIPSxx SC: ...
35
36
37
38
39
  	unsigned long lsize = cpu_scache_line_size();
  	unsigned long almask = ~(lsize - 1);
  
  	cache_op(Hit_Writeback_Inv_SD, addr & almask);
  	cache_op(Hit_Writeback_Inv_SD, (addr + size - 1) & almask);
a2c2bc4b2   Atsushi Nemoto   [MIPS] MIPS32/MIP...
40
  	blast_inv_scache_range(addr, addr + size);
9318c51ac   Chris Dearman   [MIPS] MIPS32/MIP...
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
  }
  
  static void mips_sc_enable(void)
  {
  	/* L2 cache is permanently enabled */
  }
  
  static void mips_sc_disable(void)
  {
  	/* L2 cache is permanently enabled */
  }
  
  static struct bcache_ops mips_sc_ops = {
  	.bc_enable = mips_sc_enable,
  	.bc_disable = mips_sc_disable,
  	.bc_wback_inv = mips_sc_wback_inv,
  	.bc_inv = mips_sc_inv
  };
ea31a6b20   Kevin Cernekee   MIPS: Honor L2 by...
59
60
61
62
63
64
65
66
67
68
69
  /*
   * Check if the L2 cache controller is activated on a particular platform.
   * MTI's L2 controller and the L2 cache controller of Broadcom's BMIPS
   * cores both use c0_config2's bit 12 as "L2 Bypass" bit, that is the
   * cache being disabled.  However there is no guarantee for this to be
   * true on all platforms.  In an act of stupidity the spec defined bits
   * 12..15 as implementation defined so below function will eventually have
   * to be replaced by a platform specific probe.
   */
  static inline int mips_sc_is_activated(struct cpuinfo_mips *c)
  {
081d835fa   Kevin Cernekee   MIPS: Fix build e...
70
71
  	unsigned int config2 = read_c0_config2();
  	unsigned int tmp;
ea31a6b20   Kevin Cernekee   MIPS: Honor L2 by...
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
  	/* Check the bypass bit (L2B) */
  	switch (c->cputype) {
  	case CPU_34K:
  	case CPU_74K:
  	case CPU_1004K:
  	case CPU_BMIPS5000:
  		if (config2 & (1 << 12))
  			return 0;
  	}
  
  	tmp = (config2 >> 4) & 0x0f;
  	if (0 < tmp && tmp <= 7)
  		c->scache.linesz = 2 << tmp;
  	else
  		return 0;
081d835fa   Kevin Cernekee   MIPS: Fix build e...
87
  	return 1;
ea31a6b20   Kevin Cernekee   MIPS: Honor L2 by...
88
  }
9318c51ac   Chris Dearman   [MIPS] MIPS32/MIP...
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
  static inline int __init mips_sc_probe(void)
  {
  	struct cpuinfo_mips *c = &current_cpu_data;
  	unsigned int config1, config2;
  	unsigned int tmp;
  
  	/* Mark as not present until probe completed */
  	c->scache.flags |= MIPS_CACHE_NOT_PRESENT;
  
  	/* Ignore anything but MIPSxx processors */
  	if (c->isa_level != MIPS_CPU_ISA_M32R1 &&
  	    c->isa_level != MIPS_CPU_ISA_M32R2 &&
  	    c->isa_level != MIPS_CPU_ISA_M64R1 &&
  	    c->isa_level != MIPS_CPU_ISA_M64R2)
  		return 0;
  
  	/* Does this MIPS32/MIPS64 CPU have a config2 register? */
  	config1 = read_c0_config1();
  	if (!(config1 & MIPS_CONF_M))
  		return 0;
  
  	config2 = read_c0_config2();
ea31a6b20   Kevin Cernekee   MIPS: Honor L2 by...
111
112
  
  	if (!mips_sc_is_activated(c))
9318c51ac   Chris Dearman   [MIPS] MIPS32/MIP...
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
  		return 0;
  
  	tmp = (config2 >> 8) & 0x0f;
  	if (0 <= tmp && tmp <= 7)
  		c->scache.sets = 64 << tmp;
  	else
  		return 0;
  
  	tmp = (config2 >> 0) & 0x0f;
  	if (0 <= tmp && tmp <= 7)
  		c->scache.ways = tmp + 1;
  	else
  		return 0;
  
  	c->scache.waysize = c->scache.sets * c->scache.linesz;
a2c2bc4b2   Atsushi Nemoto   [MIPS] MIPS32/MIP...
128
  	c->scache.waybit = __ffs(c->scache.waysize);
9318c51ac   Chris Dearman   [MIPS] MIPS32/MIP...
129
130
131
132
133
  
  	c->scache.flags &= ~MIPS_CACHE_NOT_PRESENT;
  
  	return 1;
  }
234fcd148   Ralf Baechle   [MIPS] Fix loads ...
134
  int __cpuinit mips_sc_init(void)
9318c51ac   Chris Dearman   [MIPS] MIPS32/MIP...
135
  {
49a89efbb   Ralf Baechle   [MIPS] Fix "no sp...
136
  	int found = mips_sc_probe();
9318c51ac   Chris Dearman   [MIPS] MIPS32/MIP...
137
138
139
140
141
142
  	if (found) {
  		mips_sc_enable();
  		bcops = &mips_sc_ops;
  	}
  	return found;
  }