diff options
Diffstat (limited to 'arch/mips/tx4938/toshiba_rbtx4938/setup.c')
-rw-r--r-- | arch/mips/tx4938/toshiba_rbtx4938/setup.c | 1124 |
1 files changed, 0 insertions, 1124 deletions
diff --git a/arch/mips/tx4938/toshiba_rbtx4938/setup.c b/arch/mips/tx4938/toshiba_rbtx4938/setup.c deleted file mode 100644 index 3a3659e8633a..000000000000 --- a/arch/mips/tx4938/toshiba_rbtx4938/setup.c +++ /dev/null | |||
@@ -1,1124 +0,0 @@ | |||
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/init.h> | ||
15 | #include <linux/types.h> | ||
16 | #include <linux/ioport.h> | ||
17 | #include <linux/delay.h> | ||
18 | #include <linux/interrupt.h> | ||
19 | #include <linux/console.h> | ||
20 | #include <linux/pci.h> | ||
21 | #include <linux/pm.h> | ||
22 | #include <linux/platform_device.h> | ||
23 | #include <linux/clk.h> | ||
24 | #include <linux/gpio.h> | ||
25 | |||
26 | #include <asm/reboot.h> | ||
27 | #include <asm/time.h> | ||
28 | #include <asm/txx9tmr.h> | ||
29 | #include <asm/io.h> | ||
30 | #include <asm/bootinfo.h> | ||
31 | #include <asm/tx4938/rbtx4938.h> | ||
32 | #ifdef CONFIG_SERIAL_TXX9 | ||
33 | #include <linux/serial_core.h> | ||
34 | #endif | ||
35 | #include <linux/spi/spi.h> | ||
36 | #include <asm/tx4938/spi.h> | ||
37 | #include <asm/txx9pio.h> | ||
38 | |||
39 | extern char * __init prom_getcmdline(void); | ||
40 | static inline void tx4938_report_pcic_status1(struct tx4938_pcic_reg *pcicptr); | ||
41 | |||
42 | /* These functions are used for rebooting or halting the machine*/ | ||
43 | extern void rbtx4938_machine_restart(char *command); | ||
44 | extern void rbtx4938_machine_halt(void); | ||
45 | extern void rbtx4938_machine_power_off(void); | ||
46 | |||
47 | /* clocks */ | ||
48 | unsigned int txx9_master_clock; | ||
49 | unsigned int txx9_cpu_clock; | ||
50 | unsigned int txx9_gbus_clock; | ||
51 | |||
52 | unsigned long rbtx4938_ce_base[8]; | ||
53 | unsigned long rbtx4938_ce_size[8]; | ||
54 | int txboard_pci66_mode; | ||
55 | static int tx4938_pcic_trdyto; /* default: disabled */ | ||
56 | static int tx4938_pcic_retryto; /* default: disabled */ | ||
57 | static int tx4938_ccfg_toeon = 1; | ||
58 | |||
59 | struct tx4938_pcic_reg *pcicptrs[4] = { | ||
60 | tx4938_pcicptr /* default setting for TX4938 */ | ||
61 | }; | ||
62 | |||
63 | static struct { | ||
64 | unsigned long base; | ||
65 | unsigned long size; | ||
66 | } phys_regions[16] __initdata; | ||
67 | static int num_phys_regions __initdata; | ||
68 | |||
69 | #define PHYS_REGION_MINSIZE 0x10000 | ||
70 | |||
71 | void rbtx4938_machine_halt(void) | ||
72 | { | ||
73 | printk(KERN_NOTICE "System Halted\n"); | ||
74 | local_irq_disable(); | ||
75 | |||
76 | while (1) | ||
77 | __asm__(".set\tmips3\n\t" | ||
78 | "wait\n\t" | ||
79 | ".set\tmips0"); | ||
80 | } | ||
81 | |||
82 | void rbtx4938_machine_power_off(void) | ||
83 | { | ||
84 | rbtx4938_machine_halt(); | ||
85 | /* no return */ | ||
86 | } | ||
87 | |||
88 | void rbtx4938_machine_restart(char *command) | ||
89 | { | ||
90 | local_irq_disable(); | ||
91 | |||
92 | printk("Rebooting..."); | ||
93 | writeb(1, rbtx4938_softresetlock_addr); | ||
94 | writeb(1, rbtx4938_sfvol_addr); | ||
95 | writeb(1, rbtx4938_softreset_addr); | ||
96 | while(1) | ||
97 | ; | ||
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 = bus.sysdata = 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 | if (early_read_config_word(hose, top_bus, current_bus, | ||
384 | pci_devfn, PCI_VENDOR_ID, | ||
385 | &vid) != PCIBIOS_SUCCESSFUL) | ||
386 | continue; | ||
387 | |||
388 | if (vid == 0xffff) continue; | ||
389 | |||
390 | /* check 66MHz capability */ | ||
391 | if (cap66 < 0) | ||
392 | cap66 = 1; | ||
393 | if (cap66) { | ||
394 | early_read_config_word(hose, top_bus, current_bus, pci_devfn, | ||
395 | PCI_STATUS, &stat); | ||
396 | if (!(stat & PCI_STATUS_66MHZ)) { | ||
397 | printk(KERN_DEBUG "PCI: %02x:%02x not 66MHz capable.\n", | ||
398 | current_bus, pci_devfn); | ||
399 | cap66 = 0; | ||
400 | break; | ||
401 | } | ||
402 | } | ||
403 | } | ||
404 | return cap66 > 0; | ||
405 | } | ||
406 | |||
407 | int __init | ||
408 | tx4938_pciclk66_setup(void) | ||
409 | { | ||
410 | int pciclk; | ||
411 | |||
412 | /* Assert M66EN */ | ||
413 | tx4938_ccfgptr->ccfg |= TX4938_CCFG_PCI66; | ||
414 | /* Double PCICLK (if possible) */ | ||
415 | if (tx4938_ccfgptr->pcfg & TX4938_PCFG_PCICLKEN_ALL) { | ||
416 | unsigned int pcidivmode = | ||
417 | tx4938_ccfgptr->ccfg & TX4938_CCFG_PCIDIVMODE_MASK; | ||
418 | switch (pcidivmode) { | ||
419 | case TX4938_CCFG_PCIDIVMODE_8: | ||
420 | case TX4938_CCFG_PCIDIVMODE_4: | ||
421 | pcidivmode = TX4938_CCFG_PCIDIVMODE_4; | ||
422 | pciclk = txx9_cpu_clock / 4; | ||
423 | break; | ||
424 | case TX4938_CCFG_PCIDIVMODE_9: | ||
425 | case TX4938_CCFG_PCIDIVMODE_4_5: | ||
426 | pcidivmode = TX4938_CCFG_PCIDIVMODE_4_5; | ||
427 | pciclk = txx9_cpu_clock * 2 / 9; | ||
428 | break; | ||
429 | case TX4938_CCFG_PCIDIVMODE_10: | ||
430 | case TX4938_CCFG_PCIDIVMODE_5: | ||
431 | pcidivmode = TX4938_CCFG_PCIDIVMODE_5; | ||
432 | pciclk = txx9_cpu_clock / 5; | ||
433 | break; | ||
434 | case TX4938_CCFG_PCIDIVMODE_11: | ||
435 | case TX4938_CCFG_PCIDIVMODE_5_5: | ||
436 | default: | ||
437 | pcidivmode = TX4938_CCFG_PCIDIVMODE_5_5; | ||
438 | pciclk = txx9_cpu_clock * 2 / 11; | ||
439 | break; | ||
440 | } | ||
441 | tx4938_ccfgptr->ccfg = | ||
442 | (tx4938_ccfgptr->ccfg & ~TX4938_CCFG_PCIDIVMODE_MASK) | ||
443 | | pcidivmode; | ||
444 | printk(KERN_DEBUG "PCICLK: ccfg:%08lx\n", | ||
445 | (unsigned long)tx4938_ccfgptr->ccfg); | ||
446 | } else { | ||
447 | pciclk = -1; | ||
448 | } | ||
449 | return pciclk; | ||
450 | } | ||
451 | |||
452 | extern struct pci_controller tx4938_pci_controller[]; | ||
453 | static int __init tx4938_pcibios_init(void) | ||
454 | { | ||
455 | unsigned long mem_base[2]; | ||
456 | unsigned long mem_size[2] = {TX4938_PCIMEM_SIZE_0, TX4938_PCIMEM_SIZE_1}; /* MAX 128M,64K */ | ||
457 | unsigned long io_base[2]; | ||
458 | unsigned long io_size[2] = {TX4938_PCIIO_SIZE_0, TX4938_PCIIO_SIZE_1}; /* MAX 16M,64K */ | ||
459 | /* TX4938 PCIC1: 64K MEM/IO is enough for ETH0,ETH1 */ | ||
460 | int extarb = !(tx4938_ccfgptr->ccfg & TX4938_CCFG_PCIXARB); | ||
461 | |||
462 | PCIBIOS_MIN_IO = 0x00001000UL; | ||
463 | |||
464 | mem_base[0] = txboard_request_phys_region_shrink(&mem_size[0]); | ||
465 | io_base[0] = txboard_request_phys_region_shrink(&io_size[0]); | ||
466 | |||
467 | printk("TX4938 PCIC -- DID:%04x VID:%04x RID:%02x Arbiter:%s\n", | ||
468 | (unsigned short)(tx4938_pcicptr->pciid >> 16), | ||
469 | (unsigned short)(tx4938_pcicptr->pciid & 0xffff), | ||
470 | (unsigned short)(tx4938_pcicptr->pciccrev & 0xff), | ||
471 | extarb ? "External" : "Internal"); | ||
472 | |||
473 | /* setup PCI area */ | ||
474 | tx4938_pci_controller[0].io_resource->start = io_base[0]; | ||
475 | tx4938_pci_controller[0].io_resource->end = (io_base[0] + io_size[0]) - 1; | ||
476 | tx4938_pci_controller[0].mem_resource->start = mem_base[0]; | ||
477 | tx4938_pci_controller[0].mem_resource->end = mem_base[0] + mem_size[0] - 1; | ||
478 | |||
479 | set_tx4938_pcicptr(0, tx4938_pcicptr); | ||
480 | |||
481 | register_pci_controller(&tx4938_pci_controller[0]); | ||
482 | |||
483 | if (tx4938_ccfgptr->ccfg & TX4938_CCFG_PCI66) { | ||
484 | printk("TX4938_CCFG_PCI66 already configured\n"); | ||
485 | txboard_pci66_mode = -1; /* already configured */ | ||
486 | } | ||
487 | |||
488 | /* Reset PCI Bus */ | ||
489 | writeb(0, rbtx4938_pcireset_addr); | ||
490 | /* Reset PCIC */ | ||
491 | tx4938_ccfgptr->clkctr |= TX4938_CLKCTR_PCIRST; | ||
492 | if (txboard_pci66_mode > 0) | ||
493 | tx4938_pciclk66_setup(); | ||
494 | mdelay(10); | ||
495 | /* clear PCIC reset */ | ||
496 | tx4938_ccfgptr->clkctr &= ~TX4938_CLKCTR_PCIRST; | ||
497 | writeb(1, rbtx4938_pcireset_addr); | ||
498 | mmiowb(); | ||
499 | tx4938_report_pcic_status1(tx4938_pcicptr); | ||
500 | |||
501 | tx4938_report_pciclk(); | ||
502 | tx4938_pcic_setup(tx4938_pcicptr, &tx4938_pci_controller[0], io_base[0], extarb); | ||
503 | if (txboard_pci66_mode == 0 && | ||
504 | txboard_pci66_check(&tx4938_pci_controller[0], 0, 0)) { | ||
505 | /* Reset PCI Bus */ | ||
506 | writeb(0, rbtx4938_pcireset_addr); | ||
507 | /* Reset PCIC */ | ||
508 | tx4938_ccfgptr->clkctr |= TX4938_CLKCTR_PCIRST; | ||
509 | tx4938_pciclk66_setup(); | ||
510 | mdelay(10); | ||
511 | /* clear PCIC reset */ | ||
512 | tx4938_ccfgptr->clkctr &= ~TX4938_CLKCTR_PCIRST; | ||
513 | writeb(1, rbtx4938_pcireset_addr); | ||
514 | mmiowb(); | ||
515 | /* Reinitialize PCIC */ | ||
516 | tx4938_report_pciclk(); | ||
517 | tx4938_pcic_setup(tx4938_pcicptr, &tx4938_pci_controller[0], io_base[0], extarb); | ||
518 | } | ||
519 | |||
520 | mem_base[1] = txboard_request_phys_region_shrink(&mem_size[1]); | ||
521 | io_base[1] = txboard_request_phys_region_shrink(&io_size[1]); | ||
522 | /* Reset PCIC1 */ | ||
523 | tx4938_ccfgptr->clkctr |= TX4938_CLKCTR_PCIC1RST; | ||
524 | /* PCI1DMD==0 => PCI1CLK==GBUSCLK/2 => PCI66 */ | ||
525 | if (!(tx4938_ccfgptr->ccfg & TX4938_CCFG_PCI1DMD)) | ||
526 | tx4938_ccfgptr->ccfg |= TX4938_CCFG_PCI1_66; | ||
527 | else | ||
528 | tx4938_ccfgptr->ccfg &= ~TX4938_CCFG_PCI1_66; | ||
529 | mdelay(10); | ||
530 | /* clear PCIC1 reset */ | ||
531 | tx4938_ccfgptr->clkctr &= ~TX4938_CLKCTR_PCIC1RST; | ||
532 | tx4938_report_pcic_status1(tx4938_pcic1ptr); | ||
533 | |||
534 | printk("TX4938 PCIC1 -- DID:%04x VID:%04x RID:%02x", | ||
535 | (unsigned short)(tx4938_pcic1ptr->pciid >> 16), | ||
536 | (unsigned short)(tx4938_pcic1ptr->pciid & 0xffff), | ||
537 | (unsigned short)(tx4938_pcic1ptr->pciccrev & 0xff)); | ||
538 | printk("%s PCICLK:%dMHz\n", | ||
539 | (tx4938_ccfgptr->ccfg & TX4938_CCFG_PCI1_66) ? " PCI66" : "", | ||
540 | txx9_gbus_clock / | ||
541 | ((tx4938_ccfgptr->ccfg & TX4938_CCFG_PCI1DMD) ? 4 : 2) / | ||
542 | 1000000); | ||
543 | |||
544 | /* assumption: CPHYSADDR(mips_io_port_base) == io_base[0] */ | ||
545 | tx4938_pci_controller[1].io_resource->start = | ||
546 | io_base[1] - io_base[0]; | ||
547 | tx4938_pci_controller[1].io_resource->end = | ||
548 | io_base[1] - io_base[0] + io_size[1] - 1; | ||
549 | tx4938_pci_controller[1].mem_resource->start = mem_base[1]; | ||
550 | tx4938_pci_controller[1].mem_resource->end = | ||
551 | mem_base[1] + mem_size[1] - 1; | ||
552 | set_tx4938_pcicptr(1, tx4938_pcic1ptr); | ||
553 | |||
554 | register_pci_controller(&tx4938_pci_controller[1]); | ||
555 | |||
556 | tx4938_pcic_setup(tx4938_pcic1ptr, &tx4938_pci_controller[1], io_base[1], extarb); | ||
557 | |||
558 | /* map ioport 0 to PCI I/O space address 0 */ | ||
559 | set_io_port_base(KSEG1 + io_base[0]); | ||
560 | |||
561 | return 0; | ||
562 | } | ||
563 | |||
564 | arch_initcall(tx4938_pcibios_init); | ||
565 | |||
566 | #endif /* CONFIG_PCI */ | ||
567 | |||
568 | /* SPI support */ | ||
569 | |||
570 | /* chip select for SPI devices */ | ||
571 | #define SEEPROM1_CS 7 /* PIO7 */ | ||
572 | #define SEEPROM2_CS 0 /* IOC */ | ||
573 | #define SEEPROM3_CS 1 /* IOC */ | ||
574 | #define SRTC_CS 2 /* IOC */ | ||
575 | |||
576 | #ifdef CONFIG_PCI | ||
577 | static int __init rbtx4938_ethaddr_init(void) | ||
578 | { | ||
579 | unsigned char dat[17]; | ||
580 | unsigned char sum; | ||
581 | int i; | ||
582 | |||
583 | /* 0-3: "MAC\0", 4-9:eth0, 10-15:eth1, 16:sum */ | ||
584 | if (spi_eeprom_read(SEEPROM1_CS, 0, dat, sizeof(dat))) { | ||
585 | printk(KERN_ERR "seeprom: read error.\n"); | ||
586 | return -ENODEV; | ||
587 | } else { | ||
588 | if (strcmp(dat, "MAC") != 0) | ||
589 | printk(KERN_WARNING "seeprom: bad signature.\n"); | ||
590 | for (i = 0, sum = 0; i < sizeof(dat); i++) | ||
591 | sum += dat[i]; | ||
592 | if (sum) | ||
593 | printk(KERN_WARNING "seeprom: bad checksum.\n"); | ||
594 | } | ||
595 | for (i = 0; i < 2; i++) { | ||
596 | unsigned int id = | ||
597 | TXX9_IRQ_BASE + (i ? TX4938_IR_ETH1 : TX4938_IR_ETH0); | ||
598 | struct platform_device *pdev; | ||
599 | if (!(tx4938_ccfgptr->pcfg & | ||
600 | (i ? TX4938_PCFG_ETH1_SEL : TX4938_PCFG_ETH0_SEL))) | ||
601 | continue; | ||
602 | pdev = platform_device_alloc("tc35815-mac", id); | ||
603 | if (!pdev || | ||
604 | platform_device_add_data(pdev, &dat[4 + 6 * i], 6) || | ||
605 | platform_device_add(pdev)) | ||
606 | platform_device_put(pdev); | ||
607 | } | ||
608 | return 0; | ||
609 | } | ||
610 | device_initcall(rbtx4938_ethaddr_init); | ||
611 | #endif /* CONFIG_PCI */ | ||
612 | |||
613 | static void __init rbtx4938_spi_setup(void) | ||
614 | { | ||
615 | /* set SPI_SEL */ | ||
616 | tx4938_ccfgptr->pcfg |= TX4938_PCFG_SPI_SEL; | ||
617 | } | ||
618 | |||
619 | static struct resource rbtx4938_fpga_resource; | ||
620 | |||
621 | static char pcode_str[8]; | ||
622 | static struct resource tx4938_reg_resource = { | ||
623 | .start = TX4938_REG_BASE, | ||
624 | .end = TX4938_REG_BASE + TX4938_REG_SIZE, | ||
625 | .name = pcode_str, | ||
626 | .flags = IORESOURCE_MEM | ||
627 | }; | ||
628 | |||
629 | void __init tx4938_board_setup(void) | ||
630 | { | ||
631 | int i; | ||
632 | unsigned long divmode; | ||
633 | int cpuclk = 0; | ||
634 | unsigned long pcode = TX4938_REV_PCODE(); | ||
635 | |||
636 | ioport_resource.start = 0x1000; | ||
637 | ioport_resource.end = 0xffffffff; | ||
638 | iomem_resource.start = 0x1000; | ||
639 | iomem_resource.end = 0xffffffff; /* expand to 4GB */ | ||
640 | |||
641 | sprintf(pcode_str, "TX%lx", pcode); | ||
642 | /* SDRAMC,EBUSC are configured by PROM */ | ||
643 | for (i = 0; i < 8; i++) { | ||
644 | if (!(tx4938_ebuscptr->cr[i] & 0x8)) | ||
645 | continue; /* disabled */ | ||
646 | rbtx4938_ce_base[i] = (unsigned long)TX4938_EBUSC_BA(i); | ||
647 | txboard_add_phys_region(rbtx4938_ce_base[i], TX4938_EBUSC_SIZE(i)); | ||
648 | } | ||
649 | |||
650 | /* clocks */ | ||
651 | if (txx9_master_clock) { | ||
652 | /* calculate gbus_clock and cpu_clock_freq from master_clock */ | ||
653 | divmode = (unsigned long)tx4938_ccfgptr->ccfg & TX4938_CCFG_DIVMODE_MASK; | ||
654 | switch (divmode) { | ||
655 | case TX4938_CCFG_DIVMODE_8: | ||
656 | case TX4938_CCFG_DIVMODE_10: | ||
657 | case TX4938_CCFG_DIVMODE_12: | ||
658 | case TX4938_CCFG_DIVMODE_16: | ||
659 | case TX4938_CCFG_DIVMODE_18: | ||
660 | txx9_gbus_clock = txx9_master_clock * 4; break; | ||
661 | default: | ||
662 | txx9_gbus_clock = txx9_master_clock; | ||
663 | } | ||
664 | switch (divmode) { | ||
665 | case TX4938_CCFG_DIVMODE_2: | ||
666 | case TX4938_CCFG_DIVMODE_8: | ||
667 | cpuclk = txx9_gbus_clock * 2; break; | ||
668 | case TX4938_CCFG_DIVMODE_2_5: | ||
669 | case TX4938_CCFG_DIVMODE_10: | ||
670 | cpuclk = txx9_gbus_clock * 5 / 2; break; | ||
671 | case TX4938_CCFG_DIVMODE_3: | ||
672 | case TX4938_CCFG_DIVMODE_12: | ||
673 | cpuclk = txx9_gbus_clock * 3; break; | ||
674 | case TX4938_CCFG_DIVMODE_4: | ||
675 | case TX4938_CCFG_DIVMODE_16: | ||
676 | cpuclk = txx9_gbus_clock * 4; break; | ||
677 | case TX4938_CCFG_DIVMODE_4_5: | ||
678 | case TX4938_CCFG_DIVMODE_18: | ||
679 | cpuclk = txx9_gbus_clock * 9 / 2; break; | ||
680 | } | ||
681 | txx9_cpu_clock = cpuclk; | ||
682 | } else { | ||
683 | if (txx9_cpu_clock == 0) { | ||
684 | txx9_cpu_clock = 300000000; /* 300MHz */ | ||
685 | } | ||
686 | /* calculate gbus_clock and master_clock from cpu_clock_freq */ | ||
687 | cpuclk = txx9_cpu_clock; | ||
688 | divmode = (unsigned long)tx4938_ccfgptr->ccfg & TX4938_CCFG_DIVMODE_MASK; | ||
689 | switch (divmode) { | ||
690 | case TX4938_CCFG_DIVMODE_2: | ||
691 | case TX4938_CCFG_DIVMODE_8: | ||
692 | txx9_gbus_clock = cpuclk / 2; break; | ||
693 | case TX4938_CCFG_DIVMODE_2_5: | ||
694 | case TX4938_CCFG_DIVMODE_10: | ||
695 | txx9_gbus_clock = cpuclk * 2 / 5; break; | ||
696 | case TX4938_CCFG_DIVMODE_3: | ||
697 | case TX4938_CCFG_DIVMODE_12: | ||
698 | txx9_gbus_clock = cpuclk / 3; break; | ||
699 | case TX4938_CCFG_DIVMODE_4: | ||
700 | case TX4938_CCFG_DIVMODE_16: | ||
701 | txx9_gbus_clock = cpuclk / 4; break; | ||
702 | case TX4938_CCFG_DIVMODE_4_5: | ||
703 | case TX4938_CCFG_DIVMODE_18: | ||
704 | txx9_gbus_clock = cpuclk * 2 / 9; break; | ||
705 | } | ||
706 | switch (divmode) { | ||
707 | case TX4938_CCFG_DIVMODE_8: | ||
708 | case TX4938_CCFG_DIVMODE_10: | ||
709 | case TX4938_CCFG_DIVMODE_12: | ||
710 | case TX4938_CCFG_DIVMODE_16: | ||
711 | case TX4938_CCFG_DIVMODE_18: | ||
712 | txx9_master_clock = txx9_gbus_clock / 4; break; | ||
713 | default: | ||
714 | txx9_master_clock = txx9_gbus_clock; | ||
715 | } | ||
716 | } | ||
717 | /* change default value to udelay/mdelay take reasonable time */ | ||
718 | loops_per_jiffy = txx9_cpu_clock / HZ / 2; | ||
719 | |||
720 | /* CCFG */ | ||
721 | /* clear WatchDogReset,BusErrorOnWrite flag (W1C) */ | ||
722 | tx4938_ccfgptr->ccfg |= TX4938_CCFG_WDRST | TX4938_CCFG_BEOW; | ||
723 | /* do reset on watchdog */ | ||
724 | tx4938_ccfgptr->ccfg |= TX4938_CCFG_WR; | ||
725 | /* clear PCIC1 reset */ | ||
726 | if (tx4938_ccfgptr->clkctr & TX4938_CLKCTR_PCIC1RST) | ||
727 | tx4938_ccfgptr->clkctr &= ~TX4938_CLKCTR_PCIC1RST; | ||
728 | |||
729 | /* enable Timeout BusError */ | ||
730 | if (tx4938_ccfg_toeon) | ||
731 | tx4938_ccfgptr->ccfg |= TX4938_CCFG_TOE; | ||
732 | |||
733 | /* DMA selection */ | ||
734 | tx4938_ccfgptr->pcfg &= ~TX4938_PCFG_DMASEL_ALL; | ||
735 | |||
736 | /* Use external clock for external arbiter */ | ||
737 | if (!(tx4938_ccfgptr->ccfg & TX4938_CCFG_PCIXARB)) | ||
738 | tx4938_ccfgptr->pcfg &= ~TX4938_PCFG_PCICLKEN_ALL; | ||
739 | |||
740 | printk("%s -- %dMHz(M%dMHz) CRIR:%08lx CCFG:%Lx PCFG:%Lx\n", | ||
741 | pcode_str, | ||
742 | cpuclk / 1000000, txx9_master_clock / 1000000, | ||
743 | (unsigned long)tx4938_ccfgptr->crir, | ||
744 | tx4938_ccfgptr->ccfg, | ||
745 | tx4938_ccfgptr->pcfg); | ||
746 | |||
747 | printk("%s SDRAMC --", pcode_str); | ||
748 | for (i = 0; i < 4; i++) { | ||
749 | unsigned long long cr = tx4938_sdramcptr->cr[i]; | ||
750 | unsigned long ram_base, ram_size; | ||
751 | if (!((unsigned long)cr & 0x00000400)) | ||
752 | continue; /* disabled */ | ||
753 | ram_base = (unsigned long)(cr >> 49) << 21; | ||
754 | ram_size = ((unsigned long)(cr >> 33) + 1) << 21; | ||
755 | if (ram_base >= 0x20000000) | ||
756 | continue; /* high memory (ignore) */ | ||
757 | printk(" CR%d:%016Lx", i, cr); | ||
758 | txboard_add_phys_region(ram_base, ram_size); | ||
759 | } | ||
760 | printk(" TR:%09Lx\n", tx4938_sdramcptr->tr); | ||
761 | |||
762 | /* SRAM */ | ||
763 | if (pcode == 0x4938 && tx4938_sramcptr->cr & 1) { | ||
764 | unsigned int size = 0x800; | ||
765 | unsigned long base = | ||
766 | (tx4938_sramcptr->cr >> (39-11)) & ~(size - 1); | ||
767 | txboard_add_phys_region(base, size); | ||
768 | } | ||
769 | |||
770 | /* TMR */ | ||
771 | for (i = 0; i < TX4938_NR_TMR; i++) | ||
772 | txx9_tmr_init(TX4938_TMR_REG(i) & 0xfffffffffULL); | ||
773 | |||
774 | /* enable DMA */ | ||
775 | for (i = 0; i < 2; i++) | ||
776 | ____raw_writeq(TX4938_DMA_MCR_MSTEN, | ||
777 | (void __iomem *)(TX4938_DMA_REG(i) + 0x50)); | ||
778 | |||
779 | /* PIO */ | ||
780 | __raw_writel(0, &tx4938_pioptr->maskcpu); | ||
781 | __raw_writel(0, &tx4938_pioptr->maskext); | ||
782 | |||
783 | /* TX4938 internal registers */ | ||
784 | if (request_resource(&iomem_resource, &tx4938_reg_resource)) | ||
785 | printk("request resource for internal registers failed\n"); | ||
786 | } | ||
787 | |||
788 | #ifdef CONFIG_PCI | ||
789 | static inline void tx4938_report_pcic_status1(struct tx4938_pcic_reg *pcicptr) | ||
790 | { | ||
791 | unsigned short pcistatus = (unsigned short)(pcicptr->pcistatus >> 16); | ||
792 | unsigned long g2pstatus = pcicptr->g2pstatus; | ||
793 | unsigned long pcicstatus = pcicptr->pcicstatus; | ||
794 | static struct { | ||
795 | unsigned long flag; | ||
796 | const char *str; | ||
797 | } pcistat_tbl[] = { | ||
798 | { PCI_STATUS_DETECTED_PARITY, "DetectedParityError" }, | ||
799 | { PCI_STATUS_SIG_SYSTEM_ERROR, "SignaledSystemError" }, | ||
800 | { PCI_STATUS_REC_MASTER_ABORT, "ReceivedMasterAbort" }, | ||
801 | { PCI_STATUS_REC_TARGET_ABORT, "ReceivedTargetAbort" }, | ||
802 | { PCI_STATUS_SIG_TARGET_ABORT, "SignaledTargetAbort" }, | ||
803 | { PCI_STATUS_PARITY, "MasterParityError" }, | ||
804 | }, g2pstat_tbl[] = { | ||
805 | { TX4938_PCIC_G2PSTATUS_TTOE, "TIOE" }, | ||
806 | { TX4938_PCIC_G2PSTATUS_RTOE, "RTOE" }, | ||
807 | }, pcicstat_tbl[] = { | ||
808 | { TX4938_PCIC_PCICSTATUS_PME, "PME" }, | ||
809 | { TX4938_PCIC_PCICSTATUS_TLB, "TLB" }, | ||
810 | { TX4938_PCIC_PCICSTATUS_NIB, "NIB" }, | ||
811 | { TX4938_PCIC_PCICSTATUS_ZIB, "ZIB" }, | ||
812 | { TX4938_PCIC_PCICSTATUS_PERR, "PERR" }, | ||
813 | { TX4938_PCIC_PCICSTATUS_SERR, "SERR" }, | ||
814 | { TX4938_PCIC_PCICSTATUS_GBE, "GBE" }, | ||
815 | { TX4938_PCIC_PCICSTATUS_IWB, "IWB" }, | ||
816 | }; | ||
817 | int i; | ||
818 | |||
819 | printk("pcistat:%04x(", pcistatus); | ||
820 | for (i = 0; i < ARRAY_SIZE(pcistat_tbl); i++) | ||
821 | if (pcistatus & pcistat_tbl[i].flag) | ||
822 | printk("%s ", pcistat_tbl[i].str); | ||
823 | printk("), g2pstatus:%08lx(", g2pstatus); | ||
824 | for (i = 0; i < ARRAY_SIZE(g2pstat_tbl); i++) | ||
825 | if (g2pstatus & g2pstat_tbl[i].flag) | ||
826 | printk("%s ", g2pstat_tbl[i].str); | ||
827 | printk("), pcicstatus:%08lx(", pcicstatus); | ||
828 | for (i = 0; i < ARRAY_SIZE(pcicstat_tbl); i++) | ||
829 | if (pcicstatus & pcicstat_tbl[i].flag) | ||
830 | printk("%s ", pcicstat_tbl[i].str); | ||
831 | printk(")\n"); | ||
832 | } | ||
833 | |||
834 | void tx4938_report_pcic_status(void) | ||
835 | { | ||
836 | int i; | ||
837 | struct tx4938_pcic_reg *pcicptr; | ||
838 | for (i = 0; (pcicptr = get_tx4938_pcicptr(i)) != NULL; i++) | ||
839 | tx4938_report_pcic_status1(pcicptr); | ||
840 | } | ||
841 | |||
842 | #endif /* CONFIG_PCI */ | ||
843 | |||
844 | void __init plat_time_init(void) | ||
845 | { | ||
846 | mips_hpt_frequency = txx9_cpu_clock / 2; | ||
847 | if (tx4938_ccfgptr->ccfg & TX4938_CCFG_TINTDIS) | ||
848 | txx9_clockevent_init(TX4938_TMR_REG(0) & 0xfffffffffULL, | ||
849 | TXX9_IRQ_BASE + TX4938_IR_TMR(0), | ||
850 | txx9_gbus_clock / 2); | ||
851 | } | ||
852 | |||
853 | void __init plat_mem_setup(void) | ||
854 | { | ||
855 | unsigned long long pcfg; | ||
856 | char *argptr; | ||
857 | |||
858 | iomem_resource.end = 0xffffffff; /* 4GB */ | ||
859 | |||
860 | if (txx9_master_clock == 0) | ||
861 | txx9_master_clock = 25000000; /* 25MHz */ | ||
862 | tx4938_board_setup(); | ||
863 | #ifndef CONFIG_PCI | ||
864 | set_io_port_base(RBTX4938_ETHER_BASE); | ||
865 | #endif | ||
866 | |||
867 | #ifdef CONFIG_SERIAL_TXX9 | ||
868 | { | ||
869 | extern int early_serial_txx9_setup(struct uart_port *port); | ||
870 | int i; | ||
871 | struct uart_port req; | ||
872 | for(i = 0; i < 2; i++) { | ||
873 | memset(&req, 0, sizeof(req)); | ||
874 | req.line = i; | ||
875 | req.iotype = UPIO_MEM; | ||
876 | req.membase = (char *)(0xff1ff300 + i * 0x100); | ||
877 | req.mapbase = 0xff1ff300 + i * 0x100; | ||
878 | req.irq = RBTX4938_IRQ_IRC_SIO(i); | ||
879 | req.flags |= UPF_BUGGY_UART /*HAVE_CTS_LINE*/; | ||
880 | req.uartclk = 50000000; | ||
881 | early_serial_txx9_setup(&req); | ||
882 | } | ||
883 | } | ||
884 | #ifdef CONFIG_SERIAL_TXX9_CONSOLE | ||
885 | argptr = prom_getcmdline(); | ||
886 | if (strstr(argptr, "console=") == NULL) { | ||
887 | strcat(argptr, " console=ttyS0,38400"); | ||
888 | } | ||
889 | #endif | ||
890 | #endif | ||
891 | |||
892 | #ifdef CONFIG_TOSHIBA_RBTX4938_MPLEX_PIO58_61 | ||
893 | printk("PIOSEL: disabling both ata and nand selection\n"); | ||
894 | local_irq_disable(); | ||
895 | tx4938_ccfgptr->pcfg &= ~(TX4938_PCFG_NDF_SEL | TX4938_PCFG_ATA_SEL); | ||
896 | #endif | ||
897 | |||
898 | #ifdef CONFIG_TOSHIBA_RBTX4938_MPLEX_NAND | ||
899 | printk("PIOSEL: enabling nand selection\n"); | ||
900 | tx4938_ccfgptr->pcfg |= TX4938_PCFG_NDF_SEL; | ||
901 | tx4938_ccfgptr->pcfg &= ~TX4938_PCFG_ATA_SEL; | ||
902 | #endif | ||
903 | |||
904 | #ifdef CONFIG_TOSHIBA_RBTX4938_MPLEX_ATA | ||
905 | printk("PIOSEL: enabling ata selection\n"); | ||
906 | tx4938_ccfgptr->pcfg |= TX4938_PCFG_ATA_SEL; | ||
907 | tx4938_ccfgptr->pcfg &= ~TX4938_PCFG_NDF_SEL; | ||
908 | #endif | ||
909 | |||
910 | #ifdef CONFIG_IP_PNP | ||
911 | argptr = prom_getcmdline(); | ||
912 | if (strstr(argptr, "ip=") == NULL) { | ||
913 | strcat(argptr, " ip=any"); | ||
914 | } | ||
915 | #endif | ||
916 | |||
917 | |||
918 | #ifdef CONFIG_FB | ||
919 | { | ||
920 | conswitchp = &dummy_con; | ||
921 | } | ||
922 | #endif | ||
923 | |||
924 | rbtx4938_spi_setup(); | ||
925 | pcfg = tx4938_ccfgptr->pcfg; /* updated */ | ||
926 | /* fixup piosel */ | ||
927 | if ((pcfg & (TX4938_PCFG_ATA_SEL | TX4938_PCFG_NDF_SEL)) == | ||
928 | TX4938_PCFG_ATA_SEL) | ||
929 | writeb((readb(rbtx4938_piosel_addr) & 0x03) | 0x04, | ||
930 | rbtx4938_piosel_addr); | ||
931 | else if ((pcfg & (TX4938_PCFG_ATA_SEL | TX4938_PCFG_NDF_SEL)) == | ||
932 | TX4938_PCFG_NDF_SEL) | ||
933 | writeb((readb(rbtx4938_piosel_addr) & 0x03) | 0x08, | ||
934 | rbtx4938_piosel_addr); | ||
935 | else | ||
936 | writeb(readb(rbtx4938_piosel_addr) & ~(0x08 | 0x04), | ||
937 | rbtx4938_piosel_addr); | ||
938 | |||
939 | rbtx4938_fpga_resource.name = "FPGA Registers"; | ||
940 | rbtx4938_fpga_resource.start = CPHYSADDR(RBTX4938_FPGA_REG_ADDR); | ||
941 | rbtx4938_fpga_resource.end = CPHYSADDR(RBTX4938_FPGA_REG_ADDR) + 0xffff; | ||
942 | rbtx4938_fpga_resource.flags = IORESOURCE_MEM | IORESOURCE_BUSY; | ||
943 | if (request_resource(&iomem_resource, &rbtx4938_fpga_resource)) | ||
944 | printk("request resource for fpga failed\n"); | ||
945 | |||
946 | _machine_restart = rbtx4938_machine_restart; | ||
947 | _machine_halt = rbtx4938_machine_halt; | ||
948 | pm_power_off = rbtx4938_machine_power_off; | ||
949 | |||
950 | writeb(0xff, rbtx4938_led_addr); | ||
951 | printk(KERN_INFO "RBTX4938 --- FPGA(Rev %02x) DIPSW:%02x,%02x\n", | ||
952 | readb(rbtx4938_fpga_rev_addr), | ||
953 | readb(rbtx4938_dipsw_addr), readb(rbtx4938_bdipsw_addr)); | ||
954 | } | ||
955 | |||
956 | static int __init rbtx4938_ne_init(void) | ||
957 | { | ||
958 | struct resource res[] = { | ||
959 | { | ||
960 | .start = RBTX4938_RTL_8019_BASE, | ||
961 | .end = RBTX4938_RTL_8019_BASE + 0x20 - 1, | ||
962 | .flags = IORESOURCE_IO, | ||
963 | }, { | ||
964 | .start = RBTX4938_RTL_8019_IRQ, | ||
965 | .flags = IORESOURCE_IRQ, | ||
966 | } | ||
967 | }; | ||
968 | struct platform_device *dev = | ||
969 | platform_device_register_simple("ne", -1, | ||
970 | res, ARRAY_SIZE(res)); | ||
971 | return IS_ERR(dev) ? PTR_ERR(dev) : 0; | ||
972 | } | ||
973 | device_initcall(rbtx4938_ne_init); | ||
974 | |||
975 | /* GPIO support */ | ||
976 | |||
977 | int gpio_to_irq(unsigned gpio) | ||
978 | { | ||
979 | return -EINVAL; | ||
980 | } | ||
981 | |||
982 | int irq_to_gpio(unsigned irq) | ||
983 | { | ||
984 | return -EINVAL; | ||
985 | } | ||
986 | |||
987 | static DEFINE_SPINLOCK(rbtx4938_spi_gpio_lock); | ||
988 | |||
989 | static void rbtx4938_spi_gpio_set(struct gpio_chip *chip, unsigned int offset, | ||
990 | int value) | ||
991 | { | ||
992 | u8 val; | ||
993 | unsigned long flags; | ||
994 | spin_lock_irqsave(&rbtx4938_spi_gpio_lock, flags); | ||
995 | val = readb(rbtx4938_spics_addr); | ||
996 | if (value) | ||
997 | val |= 1 << offset; | ||
998 | else | ||
999 | val &= ~(1 << offset); | ||
1000 | writeb(val, rbtx4938_spics_addr); | ||
1001 | mmiowb(); | ||
1002 | spin_unlock_irqrestore(&rbtx4938_spi_gpio_lock, flags); | ||
1003 | } | ||
1004 | |||
1005 | static int rbtx4938_spi_gpio_dir_out(struct gpio_chip *chip, | ||
1006 | unsigned int offset, int value) | ||
1007 | { | ||
1008 | rbtx4938_spi_gpio_set(chip, offset, value); | ||
1009 | return 0; | ||
1010 | } | ||
1011 | |||
1012 | static struct gpio_chip rbtx4938_spi_gpio_chip = { | ||
1013 | .set = rbtx4938_spi_gpio_set, | ||
1014 | .direction_output = rbtx4938_spi_gpio_dir_out, | ||
1015 | .label = "RBTX4938-SPICS", | ||
1016 | .base = 16, | ||
1017 | .ngpio = 3, | ||
1018 | }; | ||
1019 | |||
1020 | /* SPI support */ | ||
1021 | |||
1022 | static void __init txx9_spi_init(unsigned long base, int irq) | ||
1023 | { | ||
1024 | struct resource res[] = { | ||
1025 | { | ||
1026 | .start = base, | ||
1027 | .end = base + 0x20 - 1, | ||
1028 | .flags = IORESOURCE_MEM, | ||
1029 | }, { | ||
1030 | .start = irq, | ||
1031 | .flags = IORESOURCE_IRQ, | ||
1032 | }, | ||
1033 | }; | ||
1034 | platform_device_register_simple("spi_txx9", 0, | ||
1035 | res, ARRAY_SIZE(res)); | ||
1036 | } | ||
1037 | |||
1038 | static int __init rbtx4938_spi_init(void) | ||
1039 | { | ||
1040 | struct spi_board_info srtc_info = { | ||
1041 | .modalias = "rtc-rs5c348", | ||
1042 | .max_speed_hz = 1000000, /* 1.0Mbps @ Vdd 2.0V */ | ||
1043 | .bus_num = 0, | ||
1044 | .chip_select = 16 + SRTC_CS, | ||
1045 | /* Mode 1 (High-Active, Shift-Then-Sample), High Avtive CS */ | ||
1046 | .mode = SPI_MODE_1 | SPI_CS_HIGH, | ||
1047 | }; | ||
1048 | spi_register_board_info(&srtc_info, 1); | ||
1049 | spi_eeprom_register(SEEPROM1_CS); | ||
1050 | spi_eeprom_register(16 + SEEPROM2_CS); | ||
1051 | spi_eeprom_register(16 + SEEPROM3_CS); | ||
1052 | gpio_request(16 + SRTC_CS, "rtc-rs5c348"); | ||
1053 | gpio_direction_output(16 + SRTC_CS, 0); | ||
1054 | gpio_request(SEEPROM1_CS, "seeprom1"); | ||
1055 | gpio_direction_output(SEEPROM1_CS, 1); | ||
1056 | gpio_request(16 + SEEPROM2_CS, "seeprom2"); | ||
1057 | gpio_direction_output(16 + SEEPROM2_CS, 1); | ||
1058 | gpio_request(16 + SEEPROM3_CS, "seeprom3"); | ||
1059 | gpio_direction_output(16 + SEEPROM3_CS, 1); | ||
1060 | txx9_spi_init(TX4938_SPI_REG & 0xfffffffffULL, RBTX4938_IRQ_IRC_SPI); | ||
1061 | return 0; | ||
1062 | } | ||
1063 | |||
1064 | static int __init rbtx4938_arch_init(void) | ||
1065 | { | ||
1066 | txx9_gpio_init(TX4938_PIO_REG & 0xfffffffffULL, 0, 16); | ||
1067 | gpiochip_add(&rbtx4938_spi_gpio_chip); | ||
1068 | return rbtx4938_spi_init(); | ||
1069 | } | ||
1070 | arch_initcall(rbtx4938_arch_init); | ||
1071 | |||
1072 | /* Watchdog support */ | ||
1073 | |||
1074 | static int __init txx9_wdt_init(unsigned long base) | ||
1075 | { | ||
1076 | struct resource res = { | ||
1077 | .start = base, | ||
1078 | .end = base + 0x100 - 1, | ||
1079 | .flags = IORESOURCE_MEM, | ||
1080 | }; | ||
1081 | struct platform_device *dev = | ||
1082 | platform_device_register_simple("txx9wdt", -1, &res, 1); | ||
1083 | return IS_ERR(dev) ? PTR_ERR(dev) : 0; | ||
1084 | } | ||
1085 | |||
1086 | static int __init rbtx4938_wdt_init(void) | ||
1087 | { | ||
1088 | return txx9_wdt_init(TX4938_TMR_REG(2) & 0xfffffffffULL); | ||
1089 | } | ||
1090 | device_initcall(rbtx4938_wdt_init); | ||
1091 | |||
1092 | /* Minimum CLK support */ | ||
1093 | |||
1094 | struct clk *clk_get(struct device *dev, const char *id) | ||
1095 | { | ||
1096 | if (!strcmp(id, "spi-baseclk")) | ||
1097 | return (struct clk *)(txx9_gbus_clock / 2 / 4); | ||
1098 | if (!strcmp(id, "imbus_clk")) | ||
1099 | return (struct clk *)(txx9_gbus_clock / 2); | ||
1100 | return ERR_PTR(-ENOENT); | ||
1101 | } | ||
1102 | EXPORT_SYMBOL(clk_get); | ||
1103 | |||
1104 | int clk_enable(struct clk *clk) | ||
1105 | { | ||
1106 | return 0; | ||
1107 | } | ||
1108 | EXPORT_SYMBOL(clk_enable); | ||
1109 | |||
1110 | void clk_disable(struct clk *clk) | ||
1111 | { | ||
1112 | } | ||
1113 | EXPORT_SYMBOL(clk_disable); | ||
1114 | |||
1115 | unsigned long clk_get_rate(struct clk *clk) | ||
1116 | { | ||
1117 | return (unsigned long)clk; | ||
1118 | } | ||
1119 | EXPORT_SYMBOL(clk_get_rate); | ||
1120 | |||
1121 | void clk_put(struct clk *clk) | ||
1122 | { | ||
1123 | } | ||
1124 | EXPORT_SYMBOL(clk_put); | ||