diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2005-07-25 18:45:45 -0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2005-10-29 14:31:57 -0400 |
commit | 23fbee9dd5d2a41d36af49ff8e1669fb0c29fda8 (patch) | |
tree | 4e24699269b9d4d2655d961e7a0ffb29931e9b2d /arch/mips/tx4938/toshiba_rbtx4938/setup.c | |
parent | 132940401174ed04f9e8f1ae2dad6f47da26ee0a (diff) |
Support for Toshiba's RBHMA4500 eval board for the TX4938.
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/tx4938/toshiba_rbtx4938/setup.c')
-rw-r--r-- | arch/mips/tx4938/toshiba_rbtx4938/setup.c | 1035 |
1 files changed, 1035 insertions, 0 deletions
diff --git a/arch/mips/tx4938/toshiba_rbtx4938/setup.c b/arch/mips/tx4938/toshiba_rbtx4938/setup.c new file mode 100644 index 000000000000..9f1dcc8ca5a3 --- /dev/null +++ b/arch/mips/tx4938/toshiba_rbtx4938/setup.c | |||
@@ -0,0 +1,1035 @@ | |||
1 | /* | ||
2 | * linux/arch/mips/tx4938/toshiba_rbtx4938/setup.c | ||
3 | * | ||
4 | * Setup pointers to hardware-dependent routines. | ||
5 | * Copyright (C) 2000-2001 Toshiba Corporation | ||
6 | * | ||
7 | * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the | ||
8 | * terms of the GNU General Public License version 2. This program is | ||
9 | * licensed "as is" without any warranty of any kind, whether express | ||
10 | * or implied. | ||
11 | * | ||
12 | * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com) | ||
13 | */ | ||
14 | #include <linux/config.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/types.h> | ||
17 | #include <linux/ioport.h> | ||
18 | #include <linux/proc_fs.h> | ||
19 | #include <linux/delay.h> | ||
20 | #include <linux/interrupt.h> | ||
21 | #include <linux/console.h> | ||
22 | #include <linux/pci.h> | ||
23 | #include <asm/wbflush.h> | ||
24 | #include <asm/reboot.h> | ||
25 | #include <asm/irq.h> | ||
26 | #include <asm/time.h> | ||
27 | #include <asm/uaccess.h> | ||
28 | #include <asm/io.h> | ||
29 | #include <asm/bootinfo.h> | ||
30 | #include <asm/tx4938/rbtx4938.h> | ||
31 | #ifdef CONFIG_SERIAL_TXX9 | ||
32 | #include <linux/tty.h> | ||
33 | #include <linux/serial.h> | ||
34 | #include <linux/serial_core.h> | ||
35 | #endif | ||
36 | |||
37 | extern void rbtx4938_time_init(void) __init; | ||
38 | extern char * __init prom_getcmdline(void); | ||
39 | static inline void tx4938_report_pcic_status1(struct tx4938_pcic_reg *pcicptr); | ||
40 | |||
41 | /* These functions are used for rebooting or halting the machine*/ | ||
42 | extern void rbtx4938_machine_restart(char *command); | ||
43 | extern void rbtx4938_machine_halt(void); | ||
44 | extern void rbtx4938_machine_power_off(void); | ||
45 | |||
46 | /* clocks */ | ||
47 | unsigned int txx9_master_clock; | ||
48 | unsigned int txx9_cpu_clock; | ||
49 | unsigned int txx9_gbus_clock; | ||
50 | |||
51 | unsigned long rbtx4938_ce_base[8]; | ||
52 | unsigned long rbtx4938_ce_size[8]; | ||
53 | int txboard_pci66_mode; | ||
54 | static int tx4938_pcic_trdyto; /* default: disabled */ | ||
55 | static int tx4938_pcic_retryto; /* default: disabled */ | ||
56 | static int tx4938_ccfg_toeon = 1; | ||
57 | |||
58 | struct tx4938_pcic_reg *pcicptrs[4] = { | ||
59 | tx4938_pcicptr /* default setting for TX4938 */ | ||
60 | }; | ||
61 | |||
62 | static struct { | ||
63 | unsigned long base; | ||
64 | unsigned long size; | ||
65 | } phys_regions[16] __initdata; | ||
66 | static int num_phys_regions __initdata; | ||
67 | |||
68 | #define PHYS_REGION_MINSIZE 0x10000 | ||
69 | |||
70 | void rbtx4938_machine_halt(void) | ||
71 | { | ||
72 | printk(KERN_NOTICE "System Halted\n"); | ||
73 | local_irq_disable(); | ||
74 | |||
75 | while (1) | ||
76 | __asm__(".set\tmips3\n\t" | ||
77 | "wait\n\t" | ||
78 | ".set\tmips0"); | ||
79 | } | ||
80 | |||
81 | void rbtx4938_machine_power_off(void) | ||
82 | { | ||
83 | rbtx4938_machine_halt(); | ||
84 | /* no return */ | ||
85 | } | ||
86 | |||
87 | void rbtx4938_machine_restart(char *command) | ||
88 | { | ||
89 | local_irq_disable(); | ||
90 | |||
91 | printk("Rebooting..."); | ||
92 | *rbtx4938_softresetlock_ptr = 1; | ||
93 | *rbtx4938_sfvol_ptr = 1; | ||
94 | *rbtx4938_softreset_ptr = 1; | ||
95 | wbflush(); | ||
96 | |||
97 | while(1); | ||
98 | } | ||
99 | |||
100 | void __init | ||
101 | txboard_add_phys_region(unsigned long base, unsigned long size) | ||
102 | { | ||
103 | if (num_phys_regions >= ARRAY_SIZE(phys_regions)) { | ||
104 | printk("phys_region overflow\n"); | ||
105 | return; | ||
106 | } | ||
107 | phys_regions[num_phys_regions].base = base; | ||
108 | phys_regions[num_phys_regions].size = size; | ||
109 | num_phys_regions++; | ||
110 | } | ||
111 | unsigned long __init | ||
112 | txboard_find_free_phys_region(unsigned long begin, unsigned long end, | ||
113 | unsigned long size) | ||
114 | { | ||
115 | unsigned long base; | ||
116 | int i; | ||
117 | |||
118 | for (base = begin / size * size; base < end; base += size) { | ||
119 | for (i = 0; i < num_phys_regions; i++) { | ||
120 | if (phys_regions[i].size && | ||
121 | base <= phys_regions[i].base + (phys_regions[i].size - 1) && | ||
122 | base + (size - 1) >= phys_regions[i].base) | ||
123 | break; | ||
124 | } | ||
125 | if (i == num_phys_regions) | ||
126 | return base; | ||
127 | } | ||
128 | return 0; | ||
129 | } | ||
130 | unsigned long __init | ||
131 | txboard_find_free_phys_region_shrink(unsigned long begin, unsigned long end, | ||
132 | unsigned long *size) | ||
133 | { | ||
134 | unsigned long sz, base; | ||
135 | for (sz = *size; sz >= PHYS_REGION_MINSIZE; sz /= 2) { | ||
136 | base = txboard_find_free_phys_region(begin, end, sz); | ||
137 | if (base) { | ||
138 | *size = sz; | ||
139 | return base; | ||
140 | } | ||
141 | } | ||
142 | return 0; | ||
143 | } | ||
144 | unsigned long __init | ||
145 | txboard_request_phys_region_range(unsigned long begin, unsigned long end, | ||
146 | unsigned long size) | ||
147 | { | ||
148 | unsigned long base; | ||
149 | base = txboard_find_free_phys_region(begin, end, size); | ||
150 | if (base) | ||
151 | txboard_add_phys_region(base, size); | ||
152 | return base; | ||
153 | } | ||
154 | unsigned long __init | ||
155 | txboard_request_phys_region(unsigned long size) | ||
156 | { | ||
157 | unsigned long base; | ||
158 | unsigned long begin = 0, end = 0x20000000; /* search low 512MB */ | ||
159 | base = txboard_find_free_phys_region(begin, end, size); | ||
160 | if (base) | ||
161 | txboard_add_phys_region(base, size); | ||
162 | return base; | ||
163 | } | ||
164 | unsigned long __init | ||
165 | txboard_request_phys_region_shrink(unsigned long *size) | ||
166 | { | ||
167 | unsigned long base; | ||
168 | unsigned long begin = 0, end = 0x20000000; /* search low 512MB */ | ||
169 | base = txboard_find_free_phys_region_shrink(begin, end, size); | ||
170 | if (base) | ||
171 | txboard_add_phys_region(base, *size); | ||
172 | return base; | ||
173 | } | ||
174 | |||
175 | #ifdef CONFIG_PCI | ||
176 | void __init | ||
177 | tx4938_pcic_setup(struct tx4938_pcic_reg *pcicptr, | ||
178 | struct pci_controller *channel, | ||
179 | unsigned long pci_io_base, | ||
180 | int extarb) | ||
181 | { | ||
182 | int i; | ||
183 | |||
184 | /* Disable All Initiator Space */ | ||
185 | pcicptr->pciccfg &= ~(TX4938_PCIC_PCICCFG_G2PMEN(0)| | ||
186 | TX4938_PCIC_PCICCFG_G2PMEN(1)| | ||
187 | TX4938_PCIC_PCICCFG_G2PMEN(2)| | ||
188 | TX4938_PCIC_PCICCFG_G2PIOEN); | ||
189 | |||
190 | /* GB->PCI mappings */ | ||
191 | pcicptr->g2piomask = (channel->io_resource->end - channel->io_resource->start) >> 4; | ||
192 | pcicptr->g2piogbase = pci_io_base | | ||
193 | #ifdef __BIG_ENDIAN | ||
194 | TX4938_PCIC_G2PIOGBASE_ECHG | ||
195 | #else | ||
196 | TX4938_PCIC_G2PIOGBASE_BSDIS | ||
197 | #endif | ||
198 | ; | ||
199 | pcicptr->g2piopbase = 0; | ||
200 | for (i = 0; i < 3; i++) { | ||
201 | pcicptr->g2pmmask[i] = 0; | ||
202 | pcicptr->g2pmgbase[i] = 0; | ||
203 | pcicptr->g2pmpbase[i] = 0; | ||
204 | } | ||
205 | if (channel->mem_resource->end) { | ||
206 | pcicptr->g2pmmask[0] = (channel->mem_resource->end - channel->mem_resource->start) >> 4; | ||
207 | pcicptr->g2pmgbase[0] = channel->mem_resource->start | | ||
208 | #ifdef __BIG_ENDIAN | ||
209 | TX4938_PCIC_G2PMnGBASE_ECHG | ||
210 | #else | ||
211 | TX4938_PCIC_G2PMnGBASE_BSDIS | ||
212 | #endif | ||
213 | ; | ||
214 | pcicptr->g2pmpbase[0] = channel->mem_resource->start; | ||
215 | } | ||
216 | /* PCI->GB mappings (I/O 256B) */ | ||
217 | pcicptr->p2giopbase = 0; /* 256B */ | ||
218 | pcicptr->p2giogbase = 0; | ||
219 | /* PCI->GB mappings (MEM 512MB (64MB on R1.x)) */ | ||
220 | pcicptr->p2gm0plbase = 0; | ||
221 | pcicptr->p2gm0pubase = 0; | ||
222 | pcicptr->p2gmgbase[0] = 0 | | ||
223 | TX4938_PCIC_P2GMnGBASE_TMEMEN | | ||
224 | #ifdef __BIG_ENDIAN | ||
225 | TX4938_PCIC_P2GMnGBASE_TECHG | ||
226 | #else | ||
227 | TX4938_PCIC_P2GMnGBASE_TBSDIS | ||
228 | #endif | ||
229 | ; | ||
230 | /* PCI->GB mappings (MEM 16MB) */ | ||
231 | pcicptr->p2gm1plbase = 0xffffffff; | ||
232 | pcicptr->p2gm1pubase = 0xffffffff; | ||
233 | pcicptr->p2gmgbase[1] = 0; | ||
234 | /* PCI->GB mappings (MEM 1MB) */ | ||
235 | pcicptr->p2gm2pbase = 0xffffffff; /* 1MB */ | ||
236 | pcicptr->p2gmgbase[2] = 0; | ||
237 | |||
238 | pcicptr->pciccfg &= TX4938_PCIC_PCICCFG_GBWC_MASK; | ||
239 | /* Enable Initiator Memory Space */ | ||
240 | if (channel->mem_resource->end) | ||
241 | pcicptr->pciccfg |= TX4938_PCIC_PCICCFG_G2PMEN(0); | ||
242 | /* Enable Initiator I/O Space */ | ||
243 | if (channel->io_resource->end) | ||
244 | pcicptr->pciccfg |= TX4938_PCIC_PCICCFG_G2PIOEN; | ||
245 | /* Enable Initiator Config */ | ||
246 | pcicptr->pciccfg |= | ||
247 | TX4938_PCIC_PCICCFG_ICAEN | | ||
248 | TX4938_PCIC_PCICCFG_TCAR; | ||
249 | |||
250 | /* Do not use MEMMUL, MEMINF: YMFPCI card causes M_ABORT. */ | ||
251 | pcicptr->pcicfg1 = 0; | ||
252 | |||
253 | pcicptr->g2ptocnt &= ~0xffff; | ||
254 | |||
255 | if (tx4938_pcic_trdyto >= 0) { | ||
256 | pcicptr->g2ptocnt &= ~0xff; | ||
257 | pcicptr->g2ptocnt |= (tx4938_pcic_trdyto & 0xff); | ||
258 | } | ||
259 | |||
260 | if (tx4938_pcic_retryto >= 0) { | ||
261 | pcicptr->g2ptocnt &= ~0xff00; | ||
262 | pcicptr->g2ptocnt |= ((tx4938_pcic_retryto<<8) & 0xff00); | ||
263 | } | ||
264 | |||
265 | /* Clear All Local Bus Status */ | ||
266 | pcicptr->pcicstatus = TX4938_PCIC_PCICSTATUS_ALL; | ||
267 | /* Enable All Local Bus Interrupts */ | ||
268 | pcicptr->pcicmask = TX4938_PCIC_PCICSTATUS_ALL; | ||
269 | /* Clear All Initiator Status */ | ||
270 | pcicptr->g2pstatus = TX4938_PCIC_G2PSTATUS_ALL; | ||
271 | /* Enable All Initiator Interrupts */ | ||
272 | pcicptr->g2pmask = TX4938_PCIC_G2PSTATUS_ALL; | ||
273 | /* Clear All PCI Status Error */ | ||
274 | pcicptr->pcistatus = | ||
275 | (pcicptr->pcistatus & 0x0000ffff) | | ||
276 | (TX4938_PCIC_PCISTATUS_ALL << 16); | ||
277 | /* Enable All PCI Status Error Interrupts */ | ||
278 | pcicptr->pcimask = TX4938_PCIC_PCISTATUS_ALL; | ||
279 | |||
280 | if (!extarb) { | ||
281 | /* Reset Bus Arbiter */ | ||
282 | pcicptr->pbacfg = TX4938_PCIC_PBACFG_RPBA; | ||
283 | pcicptr->pbabm = 0; | ||
284 | /* Enable Bus Arbiter */ | ||
285 | pcicptr->pbacfg = TX4938_PCIC_PBACFG_PBAEN; | ||
286 | } | ||
287 | |||
288 | /* PCIC Int => IRC IRQ16 */ | ||
289 | pcicptr->pcicfg2 = | ||
290 | (pcicptr->pcicfg2 & 0xffffff00) | TX4938_IR_PCIC; | ||
291 | |||
292 | pcicptr->pcistatus = PCI_COMMAND_MASTER | | ||
293 | PCI_COMMAND_MEMORY | | ||
294 | PCI_COMMAND_PARITY | PCI_COMMAND_SERR; | ||
295 | } | ||
296 | |||
297 | int __init | ||
298 | tx4938_report_pciclk(void) | ||
299 | { | ||
300 | unsigned long pcode = TX4938_REV_PCODE(); | ||
301 | int pciclk = 0; | ||
302 | printk("TX%lx PCIC --%s PCICLK:", | ||
303 | pcode, | ||
304 | (tx4938_ccfgptr->ccfg & TX4938_CCFG_PCI66) ? " PCI66" : ""); | ||
305 | if (tx4938_ccfgptr->pcfg & TX4938_PCFG_PCICLKEN_ALL) { | ||
306 | |||
307 | switch ((unsigned long)tx4938_ccfgptr->ccfg & TX4938_CCFG_PCIDIVMODE_MASK) { | ||
308 | case TX4938_CCFG_PCIDIVMODE_4: | ||
309 | pciclk = txx9_cpu_clock / 4; break; | ||
310 | case TX4938_CCFG_PCIDIVMODE_4_5: | ||
311 | pciclk = txx9_cpu_clock * 2 / 9; break; | ||
312 | case TX4938_CCFG_PCIDIVMODE_5: | ||
313 | pciclk = txx9_cpu_clock / 5; break; | ||
314 | case TX4938_CCFG_PCIDIVMODE_5_5: | ||
315 | pciclk = txx9_cpu_clock * 2 / 11; break; | ||
316 | case TX4938_CCFG_PCIDIVMODE_8: | ||
317 | pciclk = txx9_cpu_clock / 8; break; | ||
318 | case TX4938_CCFG_PCIDIVMODE_9: | ||
319 | pciclk = txx9_cpu_clock / 9; break; | ||
320 | case TX4938_CCFG_PCIDIVMODE_10: | ||
321 | pciclk = txx9_cpu_clock / 10; break; | ||
322 | case TX4938_CCFG_PCIDIVMODE_11: | ||
323 | pciclk = txx9_cpu_clock / 11; break; | ||
324 | } | ||
325 | printk("Internal(%dMHz)", pciclk / 1000000); | ||
326 | } else { | ||
327 | printk("External"); | ||
328 | pciclk = -1; | ||
329 | } | ||
330 | printk("\n"); | ||
331 | return pciclk; | ||
332 | } | ||
333 | |||
334 | void __init set_tx4938_pcicptr(int ch, struct tx4938_pcic_reg *pcicptr) | ||
335 | { | ||
336 | pcicptrs[ch] = pcicptr; | ||
337 | } | ||
338 | |||
339 | struct tx4938_pcic_reg *get_tx4938_pcicptr(int ch) | ||
340 | { | ||
341 | return pcicptrs[ch]; | ||
342 | } | ||
343 | |||
344 | static struct pci_dev *fake_pci_dev(struct pci_controller *hose, | ||
345 | int top_bus, int busnr, int devfn) | ||
346 | { | ||
347 | static struct pci_dev dev; | ||
348 | static struct pci_bus bus; | ||
349 | |||
350 | dev.sysdata = (void *)hose; | ||
351 | dev.devfn = devfn; | ||
352 | bus.number = busnr; | ||
353 | bus.ops = hose->pci_ops; | ||
354 | bus.parent = NULL; | ||
355 | dev.bus = &bus; | ||
356 | |||
357 | return &dev; | ||
358 | } | ||
359 | |||
360 | #define EARLY_PCI_OP(rw, size, type) \ | ||
361 | static int early_##rw##_config_##size(struct pci_controller *hose, \ | ||
362 | int top_bus, int bus, int devfn, int offset, type value) \ | ||
363 | { \ | ||
364 | return pci_##rw##_config_##size( \ | ||
365 | fake_pci_dev(hose, top_bus, bus, devfn), \ | ||
366 | offset, value); \ | ||
367 | } | ||
368 | |||
369 | EARLY_PCI_OP(read, word, u16 *) | ||
370 | |||
371 | int txboard_pci66_check(struct pci_controller *hose, int top_bus, int current_bus) | ||
372 | { | ||
373 | u32 pci_devfn; | ||
374 | unsigned short vid; | ||
375 | int devfn_start = 0; | ||
376 | int devfn_stop = 0xff; | ||
377 | int cap66 = -1; | ||
378 | u16 stat; | ||
379 | |||
380 | printk("PCI: Checking 66MHz capabilities...\n"); | ||
381 | |||
382 | for (pci_devfn=devfn_start; pci_devfn<devfn_stop; pci_devfn++) { | ||
383 | early_read_config_word(hose, top_bus, current_bus, pci_devfn, | ||
384 | PCI_VENDOR_ID, &vid); | ||
385 | |||
386 | if (vid == 0xffff) continue; | ||
387 | |||
388 | /* check 66MHz capability */ | ||
389 | if (cap66 < 0) | ||
390 | cap66 = 1; | ||
391 | if (cap66) { | ||
392 | early_read_config_word(hose, top_bus, current_bus, pci_devfn, | ||
393 | PCI_STATUS, &stat); | ||
394 | if (!(stat & PCI_STATUS_66MHZ)) { | ||
395 | printk(KERN_DEBUG "PCI: %02x:%02x not 66MHz capable.\n", | ||
396 | current_bus, pci_devfn); | ||
397 | cap66 = 0; | ||
398 | break; | ||
399 | } | ||
400 | } | ||
401 | } | ||
402 | return cap66 > 0; | ||
403 | } | ||
404 | |||
405 | int __init | ||
406 | tx4938_pciclk66_setup(void) | ||
407 | { | ||
408 | int pciclk; | ||
409 | |||
410 | /* Assert M66EN */ | ||
411 | tx4938_ccfgptr->ccfg |= TX4938_CCFG_PCI66; | ||
412 | /* Double PCICLK (if possible) */ | ||
413 | if (tx4938_ccfgptr->pcfg & TX4938_PCFG_PCICLKEN_ALL) { | ||
414 | unsigned int pcidivmode = | ||
415 | tx4938_ccfgptr->ccfg & TX4938_CCFG_PCIDIVMODE_MASK; | ||
416 | switch (pcidivmode) { | ||
417 | case TX4938_CCFG_PCIDIVMODE_8: | ||
418 | case TX4938_CCFG_PCIDIVMODE_4: | ||
419 | pcidivmode = TX4938_CCFG_PCIDIVMODE_4; | ||
420 | pciclk = txx9_cpu_clock / 4; | ||
421 | break; | ||
422 | case TX4938_CCFG_PCIDIVMODE_9: | ||
423 | case TX4938_CCFG_PCIDIVMODE_4_5: | ||
424 | pcidivmode = TX4938_CCFG_PCIDIVMODE_4_5; | ||
425 | pciclk = txx9_cpu_clock * 2 / 9; | ||
426 | break; | ||
427 | case TX4938_CCFG_PCIDIVMODE_10: | ||
428 | case TX4938_CCFG_PCIDIVMODE_5: | ||
429 | pcidivmode = TX4938_CCFG_PCIDIVMODE_5; | ||
430 | pciclk = txx9_cpu_clock / 5; | ||
431 | break; | ||
432 | case TX4938_CCFG_PCIDIVMODE_11: | ||
433 | case TX4938_CCFG_PCIDIVMODE_5_5: | ||
434 | default: | ||
435 | pcidivmode = TX4938_CCFG_PCIDIVMODE_5_5; | ||
436 | pciclk = txx9_cpu_clock * 2 / 11; | ||
437 | break; | ||
438 | } | ||
439 | tx4938_ccfgptr->ccfg = | ||
440 | (tx4938_ccfgptr->ccfg & ~TX4938_CCFG_PCIDIVMODE_MASK) | ||
441 | | pcidivmode; | ||
442 | printk(KERN_DEBUG "PCICLK: ccfg:%08lx\n", | ||
443 | (unsigned long)tx4938_ccfgptr->ccfg); | ||
444 | } else { | ||
445 | pciclk = -1; | ||
446 | } | ||
447 | return pciclk; | ||
448 | } | ||
449 | |||
450 | extern struct pci_controller tx4938_pci_controller[]; | ||
451 | static int __init tx4938_pcibios_init(void) | ||
452 | { | ||
453 | unsigned long mem_base[2]; | ||
454 | unsigned long mem_size[2] = {TX4938_PCIMEM_SIZE_0,TX4938_PCIMEM_SIZE_1}; /* MAX 128M,64K */ | ||
455 | unsigned long io_base[2]; | ||
456 | unsigned long io_size[2] = {TX4938_PCIIO_SIZE_0,TX4938_PCIIO_SIZE_1}; /* MAX 16M,64K */ | ||
457 | /* TX4938 PCIC1: 64K MEM/IO is enough for ETH0,ETH1 */ | ||
458 | int extarb = !(tx4938_ccfgptr->ccfg & TX4938_CCFG_PCIXARB); | ||
459 | |||
460 | PCIBIOS_MIN_IO = 0x00001000UL; | ||
461 | PCIBIOS_MIN_MEM = 0x01000000UL; | ||
462 | |||
463 | mem_base[0] = txboard_request_phys_region_shrink(&mem_size[0]); | ||
464 | io_base[0] = txboard_request_phys_region_shrink(&io_size[0]); | ||
465 | |||
466 | printk("TX4938 PCIC -- DID:%04x VID:%04x RID:%02x Arbiter:%s\n", | ||
467 | (unsigned short)(tx4938_pcicptr->pciid >> 16), | ||
468 | (unsigned short)(tx4938_pcicptr->pciid & 0xffff), | ||
469 | (unsigned short)(tx4938_pcicptr->pciccrev & 0xff), | ||
470 | extarb ? "External" : "Internal"); | ||
471 | |||
472 | /* setup PCI area */ | ||
473 | tx4938_pci_controller[0].io_resource->start = io_base[0]; | ||
474 | tx4938_pci_controller[0].io_resource->end = (io_base[0] + io_size[0]) - 1; | ||
475 | tx4938_pci_controller[0].mem_resource->start = mem_base[0]; | ||
476 | tx4938_pci_controller[0].mem_resource->end = mem_base[0] + mem_size[0] - 1; | ||
477 | |||
478 | set_tx4938_pcicptr(0, tx4938_pcicptr); | ||
479 | |||
480 | register_pci_controller(&tx4938_pci_controller[0]); | ||
481 | |||
482 | if (tx4938_ccfgptr->ccfg & TX4938_CCFG_PCI66) { | ||
483 | printk("TX4938_CCFG_PCI66 already configured\n"); | ||
484 | txboard_pci66_mode = -1; /* already configured */ | ||
485 | } | ||
486 | |||
487 | /* Reset PCI Bus */ | ||
488 | *rbtx4938_pcireset_ptr = 0; | ||
489 | /* Reset PCIC */ | ||
490 | tx4938_ccfgptr->clkctr |= TX4938_CLKCTR_PCIRST; | ||
491 | if (txboard_pci66_mode > 0) | ||
492 | tx4938_pciclk66_setup(); | ||
493 | mdelay(10); | ||
494 | /* clear PCIC reset */ | ||
495 | tx4938_ccfgptr->clkctr &= ~TX4938_CLKCTR_PCIRST; | ||
496 | *rbtx4938_pcireset_ptr = 1; | ||
497 | wbflush(); | ||
498 | tx4938_report_pcic_status1(tx4938_pcicptr); | ||
499 | |||
500 | tx4938_report_pciclk(); | ||
501 | tx4938_pcic_setup(tx4938_pcicptr, &tx4938_pci_controller[0], io_base[0], extarb); | ||
502 | if (txboard_pci66_mode == 0 && | ||
503 | txboard_pci66_check(&tx4938_pci_controller[0], 0, 0)) { | ||
504 | /* Reset PCI Bus */ | ||
505 | *rbtx4938_pcireset_ptr = 0; | ||
506 | /* Reset PCIC */ | ||
507 | tx4938_ccfgptr->clkctr |= TX4938_CLKCTR_PCIRST; | ||
508 | tx4938_pciclk66_setup(); | ||
509 | mdelay(10); | ||
510 | /* clear PCIC reset */ | ||
511 | tx4938_ccfgptr->clkctr &= ~TX4938_CLKCTR_PCIRST; | ||
512 | *rbtx4938_pcireset_ptr = 1; | ||
513 | wbflush(); | ||
514 | /* Reinitialize PCIC */ | ||
515 | tx4938_report_pciclk(); | ||
516 | tx4938_pcic_setup(tx4938_pcicptr, &tx4938_pci_controller[0], io_base[0], extarb); | ||
517 | } | ||
518 | |||
519 | mem_base[1] = txboard_request_phys_region_shrink(&mem_size[1]); | ||
520 | io_base[1] = txboard_request_phys_region_shrink(&io_size[1]); | ||
521 | /* Reset PCIC1 */ | ||
522 | tx4938_ccfgptr->clkctr |= TX4938_CLKCTR_PCIC1RST; | ||
523 | /* PCI1DMD==0 => PCI1CLK==GBUSCLK/2 => PCI66 */ | ||
524 | if (!(tx4938_ccfgptr->ccfg & TX4938_CCFG_PCI1DMD)) | ||
525 | tx4938_ccfgptr->ccfg |= TX4938_CCFG_PCI1_66; | ||
526 | else | ||
527 | tx4938_ccfgptr->ccfg &= ~TX4938_CCFG_PCI1_66; | ||
528 | mdelay(10); | ||
529 | /* clear PCIC1 reset */ | ||
530 | tx4938_ccfgptr->clkctr &= ~TX4938_CLKCTR_PCIC1RST; | ||
531 | tx4938_report_pcic_status1(tx4938_pcic1ptr); | ||
532 | |||
533 | printk("TX4938 PCIC1 -- DID:%04x VID:%04x RID:%02x", | ||
534 | (unsigned short)(tx4938_pcic1ptr->pciid >> 16), | ||
535 | (unsigned short)(tx4938_pcic1ptr->pciid & 0xffff), | ||
536 | (unsigned short)(tx4938_pcic1ptr->pciccrev & 0xff)); | ||
537 | printk("%s PCICLK:%dMHz\n", | ||
538 | (tx4938_ccfgptr->ccfg & TX4938_CCFG_PCI1_66) ? " PCI66" : "", | ||
539 | txx9_gbus_clock / | ||
540 | ((tx4938_ccfgptr->ccfg & TX4938_CCFG_PCI1DMD) ? 4 : 2) / | ||
541 | 1000000); | ||
542 | |||
543 | /* assumption: CPHYSADDR(mips_io_port_base) == io_base[0] */ | ||
544 | tx4938_pci_controller[1].io_resource->start = | ||
545 | io_base[1] - io_base[0]; | ||
546 | tx4938_pci_controller[1].io_resource->end = | ||
547 | io_base[1] - io_base[0] + io_size[1] - 1; | ||
548 | tx4938_pci_controller[1].mem_resource->start = mem_base[1]; | ||
549 | tx4938_pci_controller[1].mem_resource->end = | ||
550 | mem_base[1] + mem_size[1] - 1; | ||
551 | set_tx4938_pcicptr(1, tx4938_pcic1ptr); | ||
552 | |||
553 | register_pci_controller(&tx4938_pci_controller[1]); | ||
554 | |||
555 | tx4938_pcic_setup(tx4938_pcic1ptr, &tx4938_pci_controller[1], io_base[1], extarb); | ||
556 | |||
557 | /* map ioport 0 to PCI I/O space address 0 */ | ||
558 | set_io_port_base(KSEG1 + io_base[0]); | ||
559 | |||
560 | return 0; | ||
561 | } | ||
562 | |||
563 | arch_initcall(tx4938_pcibios_init); | ||
564 | |||
565 | #endif /* CONFIG_PCI */ | ||
566 | |||
567 | /* SPI support */ | ||
568 | |||
569 | /* chip select for SPI devices */ | ||
570 | #define SEEPROM1_CS 7 /* PIO7 */ | ||
571 | #define SEEPROM2_CS 0 /* IOC */ | ||
572 | #define SEEPROM3_CS 1 /* IOC */ | ||
573 | #define SRTC_CS 2 /* IOC */ | ||
574 | |||
575 | static int rbtx4938_spi_cs_func(int chipid, int on) | ||
576 | { | ||
577 | unsigned char bit; | ||
578 | switch (chipid) { | ||
579 | case RBTX4938_SEEPROM1_CHIPID: | ||
580 | if (on) | ||
581 | tx4938_pioptr->dout &= ~(1 << SEEPROM1_CS); | ||
582 | else | ||
583 | tx4938_pioptr->dout |= (1 << SEEPROM1_CS); | ||
584 | return 0; | ||
585 | break; | ||
586 | case RBTX4938_SEEPROM2_CHIPID: | ||
587 | bit = (1 << SEEPROM2_CS); | ||
588 | break; | ||
589 | case RBTX4938_SEEPROM3_CHIPID: | ||
590 | bit = (1 << SEEPROM3_CS); | ||
591 | break; | ||
592 | case RBTX4938_SRTC_CHIPID: | ||
593 | bit = (1 << SRTC_CS); | ||
594 | break; | ||
595 | default: | ||
596 | return -ENODEV; | ||
597 | } | ||
598 | /* bit1,2,4 are low active, bit3 is high active */ | ||
599 | *rbtx4938_spics_ptr = | ||
600 | (*rbtx4938_spics_ptr & ~bit) | | ||
601 | ((on ? (bit ^ 0x0b) : ~(bit ^ 0x0b)) & bit); | ||
602 | return 0; | ||
603 | } | ||
604 | |||
605 | #ifdef CONFIG_PCI | ||
606 | extern int spi_eeprom_read(int chipid, int address, unsigned char *buf, int len); | ||
607 | |||
608 | int rbtx4938_get_tx4938_ethaddr(struct pci_dev *dev, unsigned char *addr) | ||
609 | { | ||
610 | struct pci_controller *channel = (struct pci_controller *)dev->bus->sysdata; | ||
611 | static unsigned char dat[17]; | ||
612 | static int read_dat = 0; | ||
613 | int ch = 0; | ||
614 | |||
615 | if (channel != &tx4938_pci_controller[1]) | ||
616 | return -ENODEV; | ||
617 | /* TX4938 PCIC1 */ | ||
618 | switch (PCI_SLOT(dev->devfn)) { | ||
619 | case TX4938_PCIC_IDSEL_AD_TO_SLOT(31): | ||
620 | ch = 0; | ||
621 | break; | ||
622 | case TX4938_PCIC_IDSEL_AD_TO_SLOT(30): | ||
623 | ch = 1; | ||
624 | break; | ||
625 | default: | ||
626 | return -ENODEV; | ||
627 | } | ||
628 | if (!read_dat) { | ||
629 | unsigned char sum; | ||
630 | int i; | ||
631 | read_dat = 1; | ||
632 | /* 0-3: "MAC\0", 4-9:eth0, 10-15:eth1, 16:sum */ | ||
633 | if (spi_eeprom_read(RBTX4938_SEEPROM1_CHIPID, | ||
634 | 0, dat, sizeof(dat))) { | ||
635 | printk(KERN_ERR "seeprom: read error.\n"); | ||
636 | } else { | ||
637 | if (strcmp(dat, "MAC") != 0) | ||
638 | printk(KERN_WARNING "seeprom: bad signature.\n"); | ||
639 | for (i = 0, sum = 0; i < sizeof(dat); i++) | ||
640 | sum += dat[i]; | ||
641 | if (sum) | ||
642 | printk(KERN_WARNING "seeprom: bad checksum.\n"); | ||
643 | } | ||
644 | } | ||
645 | memcpy(addr, &dat[4 + 6 * ch], 6); | ||
646 | return 0; | ||
647 | } | ||
648 | #endif /* CONFIG_PCI */ | ||
649 | |||
650 | extern void __init txx9_spi_init(unsigned long base, int (*cs_func)(int chipid, int on)); | ||
651 | static void __init rbtx4938_spi_setup(void) | ||
652 | { | ||
653 | /* set SPI_SEL */ | ||
654 | tx4938_ccfgptr->pcfg |= TX4938_PCFG_SPI_SEL; | ||
655 | /* chip selects for SPI devices */ | ||
656 | tx4938_pioptr->dout |= (1 << SEEPROM1_CS); | ||
657 | tx4938_pioptr->dir |= (1 << SEEPROM1_CS); | ||
658 | txx9_spi_init(TX4938_SPI_REG, rbtx4938_spi_cs_func); | ||
659 | } | ||
660 | |||
661 | static struct resource rbtx4938_fpga_resource; | ||
662 | |||
663 | static char pcode_str[8]; | ||
664 | static struct resource tx4938_reg_resource = { | ||
665 | pcode_str, TX4938_REG_BASE, TX4938_REG_BASE+TX4938_REG_SIZE, IORESOURCE_MEM | ||
666 | }; | ||
667 | |||
668 | void __init tx4938_board_setup(void) | ||
669 | { | ||
670 | int i; | ||
671 | unsigned long divmode; | ||
672 | int cpuclk = 0; | ||
673 | unsigned long pcode = TX4938_REV_PCODE(); | ||
674 | |||
675 | ioport_resource.start = 0x1000; | ||
676 | ioport_resource.end = 0xffffffff; | ||
677 | iomem_resource.start = 0x1000; | ||
678 | iomem_resource.end = 0xffffffff; /* expand to 4GB */ | ||
679 | |||
680 | sprintf(pcode_str, "TX%lx", pcode); | ||
681 | /* SDRAMC,EBUSC are configured by PROM */ | ||
682 | for (i = 0; i < 8; i++) { | ||
683 | if (!(tx4938_ebuscptr->cr[i] & 0x8)) | ||
684 | continue; /* disabled */ | ||
685 | rbtx4938_ce_base[i] = (unsigned long)TX4938_EBUSC_BA(i); | ||
686 | txboard_add_phys_region(rbtx4938_ce_base[i], TX4938_EBUSC_SIZE(i)); | ||
687 | } | ||
688 | |||
689 | /* clocks */ | ||
690 | if (txx9_master_clock) { | ||
691 | /* calculate gbus_clock and cpu_clock from master_clock */ | ||
692 | divmode = (unsigned long)tx4938_ccfgptr->ccfg & TX4938_CCFG_DIVMODE_MASK; | ||
693 | switch (divmode) { | ||
694 | case TX4938_CCFG_DIVMODE_8: | ||
695 | case TX4938_CCFG_DIVMODE_10: | ||
696 | case TX4938_CCFG_DIVMODE_12: | ||
697 | case TX4938_CCFG_DIVMODE_16: | ||
698 | case TX4938_CCFG_DIVMODE_18: | ||
699 | txx9_gbus_clock = txx9_master_clock * 4; break; | ||
700 | default: | ||
701 | txx9_gbus_clock = txx9_master_clock; | ||
702 | } | ||
703 | switch (divmode) { | ||
704 | case TX4938_CCFG_DIVMODE_2: | ||
705 | case TX4938_CCFG_DIVMODE_8: | ||
706 | cpuclk = txx9_gbus_clock * 2; break; | ||
707 | case TX4938_CCFG_DIVMODE_2_5: | ||
708 | case TX4938_CCFG_DIVMODE_10: | ||
709 | cpuclk = txx9_gbus_clock * 5 / 2; break; | ||
710 | case TX4938_CCFG_DIVMODE_3: | ||
711 | case TX4938_CCFG_DIVMODE_12: | ||
712 | cpuclk = txx9_gbus_clock * 3; break; | ||
713 | case TX4938_CCFG_DIVMODE_4: | ||
714 | case TX4938_CCFG_DIVMODE_16: | ||
715 | cpuclk = txx9_gbus_clock * 4; break; | ||
716 | case TX4938_CCFG_DIVMODE_4_5: | ||
717 | case TX4938_CCFG_DIVMODE_18: | ||
718 | cpuclk = txx9_gbus_clock * 9 / 2; break; | ||
719 | } | ||
720 | txx9_cpu_clock = cpuclk; | ||
721 | } else { | ||
722 | if (txx9_cpu_clock == 0) { | ||
723 | txx9_cpu_clock = 300000000; /* 300MHz */ | ||
724 | } | ||
725 | /* calculate gbus_clock and master_clock from cpu_clock */ | ||
726 | cpuclk = txx9_cpu_clock; | ||
727 | divmode = (unsigned long)tx4938_ccfgptr->ccfg & TX4938_CCFG_DIVMODE_MASK; | ||
728 | switch (divmode) { | ||
729 | case TX4938_CCFG_DIVMODE_2: | ||
730 | case TX4938_CCFG_DIVMODE_8: | ||
731 | txx9_gbus_clock = cpuclk / 2; break; | ||
732 | case TX4938_CCFG_DIVMODE_2_5: | ||
733 | case TX4938_CCFG_DIVMODE_10: | ||
734 | txx9_gbus_clock = cpuclk * 2 / 5; break; | ||
735 | case TX4938_CCFG_DIVMODE_3: | ||
736 | case TX4938_CCFG_DIVMODE_12: | ||
737 | txx9_gbus_clock = cpuclk / 3; break; | ||
738 | case TX4938_CCFG_DIVMODE_4: | ||
739 | case TX4938_CCFG_DIVMODE_16: | ||
740 | txx9_gbus_clock = cpuclk / 4; break; | ||
741 | case TX4938_CCFG_DIVMODE_4_5: | ||
742 | case TX4938_CCFG_DIVMODE_18: | ||
743 | txx9_gbus_clock = cpuclk * 2 / 9; break; | ||
744 | } | ||
745 | switch (divmode) { | ||
746 | case TX4938_CCFG_DIVMODE_8: | ||
747 | case TX4938_CCFG_DIVMODE_10: | ||
748 | case TX4938_CCFG_DIVMODE_12: | ||
749 | case TX4938_CCFG_DIVMODE_16: | ||
750 | case TX4938_CCFG_DIVMODE_18: | ||
751 | txx9_master_clock = txx9_gbus_clock / 4; break; | ||
752 | default: | ||
753 | txx9_master_clock = txx9_gbus_clock; | ||
754 | } | ||
755 | } | ||
756 | /* change default value to udelay/mdelay take reasonable time */ | ||
757 | loops_per_jiffy = txx9_cpu_clock / HZ / 2; | ||
758 | |||
759 | /* CCFG */ | ||
760 | /* clear WatchDogReset,BusErrorOnWrite flag (W1C) */ | ||
761 | tx4938_ccfgptr->ccfg |= TX4938_CCFG_WDRST | TX4938_CCFG_BEOW; | ||
762 | /* clear PCIC1 reset */ | ||
763 | if (tx4938_ccfgptr->clkctr & TX4938_CLKCTR_PCIC1RST) | ||
764 | tx4938_ccfgptr->clkctr &= ~TX4938_CLKCTR_PCIC1RST; | ||
765 | |||
766 | /* enable Timeout BusError */ | ||
767 | if (tx4938_ccfg_toeon) | ||
768 | tx4938_ccfgptr->ccfg |= TX4938_CCFG_TOE; | ||
769 | |||
770 | /* DMA selection */ | ||
771 | tx4938_ccfgptr->pcfg &= ~TX4938_PCFG_DMASEL_ALL; | ||
772 | |||
773 | /* Use external clock for external arbiter */ | ||
774 | if (!(tx4938_ccfgptr->ccfg & TX4938_CCFG_PCIXARB)) | ||
775 | tx4938_ccfgptr->pcfg &= ~TX4938_PCFG_PCICLKEN_ALL; | ||
776 | |||
777 | printk("%s -- %dMHz(M%dMHz) CRIR:%08lx CCFG:%Lx PCFG:%Lx\n", | ||
778 | pcode_str, | ||
779 | cpuclk / 1000000, txx9_master_clock / 1000000, | ||
780 | (unsigned long)tx4938_ccfgptr->crir, | ||
781 | tx4938_ccfgptr->ccfg, | ||
782 | tx4938_ccfgptr->pcfg); | ||
783 | |||
784 | printk("%s SDRAMC --", pcode_str); | ||
785 | for (i = 0; i < 4; i++) { | ||
786 | unsigned long long cr = tx4938_sdramcptr->cr[i]; | ||
787 | unsigned long ram_base, ram_size; | ||
788 | if (!((unsigned long)cr & 0x00000400)) | ||
789 | continue; /* disabled */ | ||
790 | ram_base = (unsigned long)(cr >> 49) << 21; | ||
791 | ram_size = ((unsigned long)(cr >> 33) + 1) << 21; | ||
792 | if (ram_base >= 0x20000000) | ||
793 | continue; /* high memory (ignore) */ | ||
794 | printk(" CR%d:%016Lx", i, cr); | ||
795 | txboard_add_phys_region(ram_base, ram_size); | ||
796 | } | ||
797 | printk(" TR:%09Lx\n", tx4938_sdramcptr->tr); | ||
798 | |||
799 | /* SRAM */ | ||
800 | if (pcode == 0x4938 && tx4938_sramcptr->cr & 1) { | ||
801 | unsigned int size = 0x800; | ||
802 | unsigned long base = | ||
803 | (tx4938_sramcptr->cr >> (39-11)) & ~(size - 1); | ||
804 | txboard_add_phys_region(base, size); | ||
805 | } | ||
806 | |||
807 | /* IRC */ | ||
808 | /* disable interrupt control */ | ||
809 | tx4938_ircptr->cer = 0; | ||
810 | |||
811 | /* TMR */ | ||
812 | /* disable all timers */ | ||
813 | for (i = 0; i < TX4938_NR_TMR; i++) { | ||
814 | tx4938_tmrptr(i)->tcr = 0x00000020; | ||
815 | tx4938_tmrptr(i)->tisr = 0; | ||
816 | tx4938_tmrptr(i)->cpra = 0xffffffff; | ||
817 | tx4938_tmrptr(i)->itmr = 0; | ||
818 | tx4938_tmrptr(i)->ccdr = 0; | ||
819 | tx4938_tmrptr(i)->pgmr = 0; | ||
820 | } | ||
821 | |||
822 | /* enable DMA */ | ||
823 | TX4938_WR64(0xff1fb150, TX4938_DMA_MCR_MSTEN); | ||
824 | TX4938_WR64(0xff1fb950, TX4938_DMA_MCR_MSTEN); | ||
825 | |||
826 | /* PIO */ | ||
827 | tx4938_pioptr->maskcpu = 0; | ||
828 | tx4938_pioptr->maskext = 0; | ||
829 | |||
830 | /* TX4938 internal registers */ | ||
831 | if (request_resource(&iomem_resource, &tx4938_reg_resource)) | ||
832 | printk("request resource for internal registers failed\n"); | ||
833 | } | ||
834 | |||
835 | #ifdef CONFIG_PCI | ||
836 | static inline void tx4938_report_pcic_status1(struct tx4938_pcic_reg *pcicptr) | ||
837 | { | ||
838 | unsigned short pcistatus = (unsigned short)(pcicptr->pcistatus >> 16); | ||
839 | unsigned long g2pstatus = pcicptr->g2pstatus; | ||
840 | unsigned long pcicstatus = pcicptr->pcicstatus; | ||
841 | static struct { | ||
842 | unsigned long flag; | ||
843 | const char *str; | ||
844 | } pcistat_tbl[] = { | ||
845 | { PCI_STATUS_DETECTED_PARITY, "DetectedParityError" }, | ||
846 | { PCI_STATUS_SIG_SYSTEM_ERROR, "SignaledSystemError" }, | ||
847 | { PCI_STATUS_REC_MASTER_ABORT, "ReceivedMasterAbort" }, | ||
848 | { PCI_STATUS_REC_TARGET_ABORT, "ReceivedTargetAbort" }, | ||
849 | { PCI_STATUS_SIG_TARGET_ABORT, "SignaledTargetAbort" }, | ||
850 | { PCI_STATUS_PARITY, "MasterParityError" }, | ||
851 | }, g2pstat_tbl[] = { | ||
852 | { TX4938_PCIC_G2PSTATUS_TTOE, "TIOE" }, | ||
853 | { TX4938_PCIC_G2PSTATUS_RTOE, "RTOE" }, | ||
854 | }, pcicstat_tbl[] = { | ||
855 | { TX4938_PCIC_PCICSTATUS_PME, "PME" }, | ||
856 | { TX4938_PCIC_PCICSTATUS_TLB, "TLB" }, | ||
857 | { TX4938_PCIC_PCICSTATUS_NIB, "NIB" }, | ||
858 | { TX4938_PCIC_PCICSTATUS_ZIB, "ZIB" }, | ||
859 | { TX4938_PCIC_PCICSTATUS_PERR, "PERR" }, | ||
860 | { TX4938_PCIC_PCICSTATUS_SERR, "SERR" }, | ||
861 | { TX4938_PCIC_PCICSTATUS_GBE, "GBE" }, | ||
862 | { TX4938_PCIC_PCICSTATUS_IWB, "IWB" }, | ||
863 | }; | ||
864 | int i; | ||
865 | |||
866 | printk("pcistat:%04x(", pcistatus); | ||
867 | for (i = 0; i < ARRAY_SIZE(pcistat_tbl); i++) | ||
868 | if (pcistatus & pcistat_tbl[i].flag) | ||
869 | printk("%s ", pcistat_tbl[i].str); | ||
870 | printk("), g2pstatus:%08lx(", g2pstatus); | ||
871 | for (i = 0; i < ARRAY_SIZE(g2pstat_tbl); i++) | ||
872 | if (g2pstatus & g2pstat_tbl[i].flag) | ||
873 | printk("%s ", g2pstat_tbl[i].str); | ||
874 | printk("), pcicstatus:%08lx(", pcicstatus); | ||
875 | for (i = 0; i < ARRAY_SIZE(pcicstat_tbl); i++) | ||
876 | if (pcicstatus & pcicstat_tbl[i].flag) | ||
877 | printk("%s ", pcicstat_tbl[i].str); | ||
878 | printk(")\n"); | ||
879 | } | ||
880 | |||
881 | void tx4938_report_pcic_status(void) | ||
882 | { | ||
883 | int i; | ||
884 | struct tx4938_pcic_reg *pcicptr; | ||
885 | for (i = 0; (pcicptr = get_tx4938_pcicptr(i)) != NULL; i++) | ||
886 | tx4938_report_pcic_status1(pcicptr); | ||
887 | } | ||
888 | |||
889 | #endif /* CONFIG_PCI */ | ||
890 | |||
891 | /* We use onchip r4k counter or TMR timer as our system wide timer | ||
892 | * interrupt running at 100HZ. */ | ||
893 | |||
894 | extern void __init rtc_rx5c348_init(int chipid); | ||
895 | void __init rbtx4938_time_init(void) | ||
896 | { | ||
897 | rtc_rx5c348_init(RBTX4938_SRTC_CHIPID); | ||
898 | mips_hpt_frequency = txx9_cpu_clock / 2; | ||
899 | } | ||
900 | |||
901 | void __init toshiba_rbtx4938_setup(void) | ||
902 | { | ||
903 | unsigned long long pcfg; | ||
904 | char *argptr; | ||
905 | |||
906 | iomem_resource.end = 0xffffffff; /* 4GB */ | ||
907 | |||
908 | if (txx9_master_clock == 0) | ||
909 | txx9_master_clock = 25000000; /* 25MHz */ | ||
910 | tx4938_board_setup(); | ||
911 | /* setup irq stuff */ | ||
912 | TX4938_WR(TX4938_MKA(TX4938_IRC_IRDM0), 0x00000000); /* irq trigger */ | ||
913 | TX4938_WR(TX4938_MKA(TX4938_IRC_IRDM1), 0x00000000); /* irq trigger */ | ||
914 | /* setup serial stuff */ | ||
915 | TX4938_WR(0xff1ff314, 0x00000000); /* h/w flow control off */ | ||
916 | TX4938_WR(0xff1ff414, 0x00000000); /* h/w flow control off */ | ||
917 | |||
918 | #ifndef CONFIG_PCI | ||
919 | set_io_port_base(RBTX4938_ETHER_BASE); | ||
920 | #endif | ||
921 | |||
922 | #ifdef CONFIG_SERIAL_TXX9 | ||
923 | { | ||
924 | extern int early_serial_txx9_setup(struct uart_port *port); | ||
925 | int i; | ||
926 | struct uart_port req; | ||
927 | for(i = 0; i < 2; i++) { | ||
928 | memset(&req, 0, sizeof(req)); | ||
929 | req.line = i; | ||
930 | req.iotype = UPIO_MEM; | ||
931 | req.membase = (char *)(0xff1ff300 + i * 0x100); | ||
932 | req.mapbase = 0xff1ff300 + i * 0x100; | ||
933 | req.irq = 32 + i; | ||
934 | req.flags |= UPF_BUGGY_UART /*HAVE_CTS_LINE*/; | ||
935 | req.uartclk = 50000000; | ||
936 | early_serial_txx9_setup(&req); | ||
937 | } | ||
938 | } | ||
939 | #ifdef CONFIG_SERIAL_TXX9_CONSOLE | ||
940 | argptr = prom_getcmdline(); | ||
941 | if (strstr(argptr, "console=") == NULL) { | ||
942 | strcat(argptr, " console=ttyS0,38400"); | ||
943 | } | ||
944 | #endif | ||
945 | #endif | ||
946 | |||
947 | #ifdef CONFIG_TOSHIBA_RBTX4938_MPLEX_PIO58_61 | ||
948 | printk("PIOSEL: disabling both ata and nand selection\n"); | ||
949 | local_irq_disable(); | ||
950 | tx4938_ccfgptr->pcfg &= ~(TX4938_PCFG_NDF_SEL | TX4938_PCFG_ATA_SEL); | ||
951 | #endif | ||
952 | |||
953 | #ifdef CONFIG_TOSHIBA_RBTX4938_MPLEX_NAND | ||
954 | printk("PIOSEL: enabling nand selection\n"); | ||
955 | tx4938_ccfgptr->pcfg |= TX4938_PCFG_NDF_SEL; | ||
956 | tx4938_ccfgptr->pcfg &= ~TX4938_PCFG_ATA_SEL; | ||
957 | #endif | ||
958 | |||
959 | #ifdef CONFIG_TOSHIBA_RBTX4938_MPLEX_ATA | ||
960 | printk("PIOSEL: enabling ata selection\n"); | ||
961 | tx4938_ccfgptr->pcfg |= TX4938_PCFG_ATA_SEL; | ||
962 | tx4938_ccfgptr->pcfg &= ~TX4938_PCFG_NDF_SEL; | ||
963 | #endif | ||
964 | |||
965 | #ifdef CONFIG_IP_PNP | ||
966 | argptr = prom_getcmdline(); | ||
967 | if (strstr(argptr, "ip=") == NULL) { | ||
968 | strcat(argptr, " ip=any"); | ||
969 | } | ||
970 | #endif | ||
971 | |||
972 | |||
973 | #ifdef CONFIG_FB | ||
974 | { | ||
975 | conswitchp = &dummy_con; | ||
976 | } | ||
977 | #endif | ||
978 | |||
979 | rbtx4938_spi_setup(); | ||
980 | pcfg = tx4938_ccfgptr->pcfg; /* updated */ | ||
981 | /* fixup piosel */ | ||
982 | if ((pcfg & (TX4938_PCFG_ATA_SEL | TX4938_PCFG_NDF_SEL)) == | ||
983 | TX4938_PCFG_ATA_SEL) { | ||
984 | *rbtx4938_piosel_ptr = (*rbtx4938_piosel_ptr & 0x03) | 0x04; | ||
985 | } | ||
986 | else if ((pcfg & (TX4938_PCFG_ATA_SEL | TX4938_PCFG_NDF_SEL)) == | ||
987 | TX4938_PCFG_NDF_SEL) { | ||
988 | *rbtx4938_piosel_ptr = (*rbtx4938_piosel_ptr & 0x03) | 0x08; | ||
989 | } | ||
990 | else { | ||
991 | *rbtx4938_piosel_ptr &= ~(0x08 | 0x04); | ||
992 | } | ||
993 | |||
994 | rbtx4938_fpga_resource.name = "FPGA Registers"; | ||
995 | rbtx4938_fpga_resource.start = CPHYSADDR(RBTX4938_FPGA_REG_ADDR); | ||
996 | rbtx4938_fpga_resource.end = CPHYSADDR(RBTX4938_FPGA_REG_ADDR) + 0xffff; | ||
997 | rbtx4938_fpga_resource.flags = IORESOURCE_MEM | IORESOURCE_BUSY; | ||
998 | if (request_resource(&iomem_resource, &rbtx4938_fpga_resource)) | ||
999 | printk("request resource for fpga failed\n"); | ||
1000 | |||
1001 | /* disable all OnBoard I/O interrupts */ | ||
1002 | *rbtx4938_imask_ptr = 0; | ||
1003 | |||
1004 | _machine_restart = rbtx4938_machine_restart; | ||
1005 | _machine_halt = rbtx4938_machine_halt; | ||
1006 | _machine_power_off = rbtx4938_machine_power_off; | ||
1007 | |||
1008 | *rbtx4938_led_ptr = 0xff; | ||
1009 | printk("RBTX4938 --- FPGA(Rev %02x)", *rbtx4938_fpga_rev_ptr); | ||
1010 | printk(" DIPSW:%02x,%02x\n", | ||
1011 | *rbtx4938_dipsw_ptr, *rbtx4938_bdipsw_ptr); | ||
1012 | } | ||
1013 | |||
1014 | #ifdef CONFIG_PROC_FS | ||
1015 | extern void spi_eeprom_proc_create(struct proc_dir_entry *dir, int chipid); | ||
1016 | static int __init tx4938_spi_proc_setup(void) | ||
1017 | { | ||
1018 | struct proc_dir_entry *tx4938_spi_eeprom_dir; | ||
1019 | |||
1020 | tx4938_spi_eeprom_dir = proc_mkdir("spi_eeprom", 0); | ||
1021 | |||
1022 | if (!tx4938_spi_eeprom_dir) | ||
1023 | return -ENOMEM; | ||
1024 | |||
1025 | /* don't allow user access to RBTX4938_SEEPROM1_CHIPID | ||
1026 | * as it contains eth0 and eth1 MAC addresses | ||
1027 | */ | ||
1028 | spi_eeprom_proc_create(tx4938_spi_eeprom_dir, RBTX4938_SEEPROM2_CHIPID); | ||
1029 | spi_eeprom_proc_create(tx4938_spi_eeprom_dir, RBTX4938_SEEPROM3_CHIPID); | ||
1030 | |||
1031 | return 0; | ||
1032 | } | ||
1033 | |||
1034 | __initcall(tx4938_spi_proc_setup); | ||
1035 | #endif | ||