This source file includes following definitions.
- get_bank_addr
- get_bank_size
- get_bank_config
- probe_memory
- sgimc_init
- prom_meminit
- prom_free_prom_memory
1
2
3
4
5
6
7
8
9
10
11 #include <linux/init.h>
12 #include <linux/export.h>
13 #include <linux/kernel.h>
14 #include <linux/spinlock.h>
15
16 #include <asm/io.h>
17 #include <asm/bootinfo.h>
18 #include <asm/sgialib.h>
19 #include <asm/sgi/mc.h>
20 #include <asm/sgi/hpc3.h>
21 #include <asm/sgi/ip22.h>
22
23 struct sgimc_regs *sgimc;
24
25 EXPORT_SYMBOL(sgimc);
26
27 static inline unsigned long get_bank_addr(unsigned int memconfig)
28 {
29 return (memconfig & SGIMC_MCONFIG_BASEADDR) << ((sgimc->systemid & SGIMC_SYSID_MASKREV) >= 5 ? 24 : 22);
30 }
31
32 static inline unsigned long get_bank_size(unsigned int memconfig)
33 {
34 return ((memconfig & SGIMC_MCONFIG_RMASK) + 0x0100) << ((sgimc->systemid & SGIMC_SYSID_MASKREV) >= 5 ? 16 : 14);
35 }
36
37 static inline unsigned int get_bank_config(int bank)
38 {
39 unsigned int res = bank > 1 ? sgimc->mconfig1 : sgimc->mconfig0;
40 return bank % 2 ? res & 0xffff : res >> 16;
41 }
42
43 struct mem {
44 unsigned long addr;
45 unsigned long size;
46 };
47
48
49
50
51 static void __init probe_memory(void)
52 {
53 int i, j, found, cnt = 0;
54 struct mem bank[4];
55 struct mem space[2] = {{SGIMC_SEG0_BADDR, 0}, {SGIMC_SEG1_BADDR, 0}};
56
57 printk(KERN_INFO "MC: Probing memory configuration:\n");
58 for (i = 0; i < ARRAY_SIZE(bank); i++) {
59 unsigned int tmp = get_bank_config(i);
60 if (!(tmp & SGIMC_MCONFIG_BVALID))
61 continue;
62
63 bank[cnt].size = get_bank_size(tmp);
64 bank[cnt].addr = get_bank_addr(tmp);
65 printk(KERN_INFO " bank%d: %3ldM @ %08lx\n",
66 i, bank[cnt].size / 1024 / 1024, bank[cnt].addr);
67 cnt++;
68 }
69
70
71 do {
72 unsigned long addr, size;
73
74 found = 0;
75 for (i = 1; i < cnt; i++)
76 if (bank[i-1].addr > bank[i].addr) {
77 addr = bank[i].addr;
78 size = bank[i].size;
79 bank[i].addr = bank[i-1].addr;
80 bank[i].size = bank[i-1].size;
81 bank[i-1].addr = addr;
82 bank[i-1].size = size;
83 found = 1;
84 }
85 } while (found);
86
87
88 for (i = 0; i < cnt; i++) {
89 found = 0;
90 for (j = 0; j < ARRAY_SIZE(space) && !found; j++)
91 if (space[j].addr + space[j].size == bank[i].addr) {
92 space[j].size += bank[i].size;
93 found = 1;
94 }
95
96 if (!found)
97 printk(KERN_CRIT "MC: Memory configuration mismatch "
98 "(%08lx), expect Bus Error soon\n",
99 bank[i].addr);
100 }
101
102 for (i = 0; i < ARRAY_SIZE(space); i++)
103 if (space[i].size)
104 add_memory_region(space[i].addr, space[i].size,
105 BOOT_MEM_RAM);
106 }
107
108 void __init sgimc_init(void)
109 {
110 u32 tmp;
111
112
113 sgimc = (struct sgimc_regs *)
114 ioremap(SGIMC_BASE, sizeof(struct sgimc_regs));
115
116 printk(KERN_INFO "MC: SGI memory controller Revision %d\n",
117 (int) sgimc->systemid & SGIMC_SYSID_MASKREV);
118
119
120
121
122
123
124
125
126
127 tmp = sgimc->cpuctrl0;
128 tmp &= ~SGIMC_CCTRL0_WDOG;
129 sgimc->cpuctrl0 = tmp;
130
131
132
133
134
135
136 sgimc->cstat = sgimc->gstat = 0;
137
138
139
140
141
142 tmp = sgimc->cpuctrl0;
143 #ifndef CONFIG_SGI_IP28
144 tmp |= SGIMC_CCTRL0_EPERRGIO | SGIMC_CCTRL0_EPERRMEM;
145 #endif
146 tmp |= SGIMC_CCTRL0_R4KNOCHKPARR;
147 sgimc->cpuctrl0 = tmp;
148
149
150
151
152 tmp = sgimc->cpuctrl1;
153 tmp &= ~0xf;
154 tmp |= 0xd;
155 sgimc->cpuctrl1 = tmp;
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171 sgimc->divider = 0x101;
172
173
174
175
176
177
178
179
180
181 tmp = sgimc->giopar & SGIMC_GIOPAR_GFX64;
182 tmp |= SGIMC_GIOPAR_HPC64;
183 tmp |= SGIMC_GIOPAR_ONEBUS;
184
185 if (ip22_is_fullhouse()) {
186
187 if (SGIOC_SYSID_BOARDREV(sgioc->sysid) < 2) {
188 tmp |= SGIMC_GIOPAR_HPC264;
189 tmp |= SGIMC_GIOPAR_PLINEEXP0;
190 tmp |= SGIMC_GIOPAR_MASTEREXP1;
191 tmp |= SGIMC_GIOPAR_RTIMEEXP0;
192 } else {
193 tmp |= SGIMC_GIOPAR_HPC264;
194 tmp |= SGIMC_GIOPAR_PLINEEXP0;
195 tmp |= SGIMC_GIOPAR_PLINEEXP1;
196 tmp |= SGIMC_GIOPAR_MASTEREISA;
197 }
198 } else {
199
200 tmp |= SGIMC_GIOPAR_EISA64;
201 tmp |= SGIMC_GIOPAR_MASTEREISA;
202 }
203 sgimc->giopar = tmp;
204
205 probe_memory();
206 }
207
208 void __init prom_meminit(void) {}
209 void __init prom_free_prom_memory(void)
210 {
211 #ifdef CONFIG_SGI_IP28
212 u32 mconfig1;
213 unsigned long flags;
214 spinlock_t lock;
215
216
217
218
219
220
221 spin_lock_irqsave(&lock, flags);
222 mconfig1 = sgimc->mconfig1;
223
224 sgimc->mconfig1 = (mconfig1 & 0xffff0000) | 0x2060;
225 iob();
226
227 *(unsigned long *)PHYS_TO_XKSEG_UNCACHED(0x60000000) = 0;
228 iob();
229
230 sgimc->cmacc = (sgimc->cmacc & ~0xf) | 4;
231 iob();
232
233 sgimc->mconfig1 = mconfig1;
234 iob();
235 spin_unlock_irqrestore(&lock, flags);
236 #endif
237 }