diff options
Diffstat (limited to 'arch/mips/txx9/rbtx4938/setup.c')
-rw-r--r-- | arch/mips/txx9/rbtx4938/setup.c | 625 |
1 files changed, 625 insertions, 0 deletions
diff --git a/arch/mips/txx9/rbtx4938/setup.c b/arch/mips/txx9/rbtx4938/setup.c new file mode 100644 index 000000000000..aaa987ae0f83 --- /dev/null +++ b/arch/mips/txx9/rbtx4938/setup.c | |||
@@ -0,0 +1,625 @@ | |||
1 | /* | ||
2 | * Setup pointers to hardware-dependent routines. | ||
3 | * Copyright (C) 2000-2001 Toshiba Corporation | ||
4 | * | ||
5 | * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the | ||
6 | * terms of the GNU General Public License version 2. This program is | ||
7 | * licensed "as is" without any warranty of any kind, whether express | ||
8 | * or implied. | ||
9 | * | ||
10 | * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com) | ||
11 | */ | ||
12 | #include <linux/init.h> | ||
13 | #include <linux/types.h> | ||
14 | #include <linux/ioport.h> | ||
15 | #include <linux/delay.h> | ||
16 | #include <linux/interrupt.h> | ||
17 | #include <linux/console.h> | ||
18 | #include <linux/pm.h> | ||
19 | #include <linux/platform_device.h> | ||
20 | #include <linux/gpio.h> | ||
21 | |||
22 | #include <asm/reboot.h> | ||
23 | #include <asm/time.h> | ||
24 | #include <asm/txx9tmr.h> | ||
25 | #include <asm/io.h> | ||
26 | #include <asm/txx9/generic.h> | ||
27 | #include <asm/txx9/pci.h> | ||
28 | #include <asm/txx9/rbtx4938.h> | ||
29 | #ifdef CONFIG_SERIAL_TXX9 | ||
30 | #include <linux/serial_core.h> | ||
31 | #endif | ||
32 | #include <linux/spi/spi.h> | ||
33 | #include <asm/txx9/spi.h> | ||
34 | #include <asm/txx9pio.h> | ||
35 | |||
36 | static int tx4938_ccfg_toeon = 1; | ||
37 | |||
38 | static void rbtx4938_machine_halt(void) | ||
39 | { | ||
40 | printk(KERN_NOTICE "System Halted\n"); | ||
41 | local_irq_disable(); | ||
42 | |||
43 | while (1) | ||
44 | __asm__(".set\tmips3\n\t" | ||
45 | "wait\n\t" | ||
46 | ".set\tmips0"); | ||
47 | } | ||
48 | |||
49 | static void rbtx4938_machine_power_off(void) | ||
50 | { | ||
51 | rbtx4938_machine_halt(); | ||
52 | /* no return */ | ||
53 | } | ||
54 | |||
55 | static void rbtx4938_machine_restart(char *command) | ||
56 | { | ||
57 | local_irq_disable(); | ||
58 | |||
59 | printk("Rebooting..."); | ||
60 | writeb(1, rbtx4938_softresetlock_addr); | ||
61 | writeb(1, rbtx4938_sfvol_addr); | ||
62 | writeb(1, rbtx4938_softreset_addr); | ||
63 | while(1) | ||
64 | ; | ||
65 | } | ||
66 | |||
67 | static void __init rbtx4938_pci_setup(void) | ||
68 | { | ||
69 | #ifdef CONFIG_PCI | ||
70 | int extarb = !(__raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_PCIARB); | ||
71 | struct pci_controller *c = &txx9_primary_pcic; | ||
72 | |||
73 | register_pci_controller(c); | ||
74 | |||
75 | if (__raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_PCI66) | ||
76 | txx9_pci_option = | ||
77 | (txx9_pci_option & ~TXX9_PCI_OPT_CLK_MASK) | | ||
78 | TXX9_PCI_OPT_CLK_66; /* already configured */ | ||
79 | |||
80 | /* Reset PCI Bus */ | ||
81 | writeb(0, rbtx4938_pcireset_addr); | ||
82 | /* Reset PCIC */ | ||
83 | txx9_set64(&tx4938_ccfgptr->clkctr, TX4938_CLKCTR_PCIRST); | ||
84 | if ((txx9_pci_option & TXX9_PCI_OPT_CLK_MASK) == | ||
85 | TXX9_PCI_OPT_CLK_66) | ||
86 | tx4938_pciclk66_setup(); | ||
87 | mdelay(10); | ||
88 | /* clear PCIC reset */ | ||
89 | txx9_clear64(&tx4938_ccfgptr->clkctr, TX4938_CLKCTR_PCIRST); | ||
90 | writeb(1, rbtx4938_pcireset_addr); | ||
91 | iob(); | ||
92 | |||
93 | tx4938_report_pciclk(); | ||
94 | tx4927_pcic_setup(tx4938_pcicptr, c, extarb); | ||
95 | if ((txx9_pci_option & TXX9_PCI_OPT_CLK_MASK) == | ||
96 | TXX9_PCI_OPT_CLK_AUTO && | ||
97 | txx9_pci66_check(c, 0, 0)) { | ||
98 | /* Reset PCI Bus */ | ||
99 | writeb(0, rbtx4938_pcireset_addr); | ||
100 | /* Reset PCIC */ | ||
101 | txx9_set64(&tx4938_ccfgptr->clkctr, TX4938_CLKCTR_PCIRST); | ||
102 | tx4938_pciclk66_setup(); | ||
103 | mdelay(10); | ||
104 | /* clear PCIC reset */ | ||
105 | txx9_clear64(&tx4938_ccfgptr->clkctr, TX4938_CLKCTR_PCIRST); | ||
106 | writeb(1, rbtx4938_pcireset_addr); | ||
107 | iob(); | ||
108 | /* Reinitialize PCIC */ | ||
109 | tx4938_report_pciclk(); | ||
110 | tx4927_pcic_setup(tx4938_pcicptr, c, extarb); | ||
111 | } | ||
112 | |||
113 | if (__raw_readq(&tx4938_ccfgptr->pcfg) & | ||
114 | (TX4938_PCFG_ETH0_SEL|TX4938_PCFG_ETH1_SEL)) { | ||
115 | /* Reset PCIC1 */ | ||
116 | txx9_set64(&tx4938_ccfgptr->clkctr, TX4938_CLKCTR_PCIC1RST); | ||
117 | /* PCI1DMD==0 => PCI1CLK==GBUSCLK/2 => PCI66 */ | ||
118 | if (!(__raw_readq(&tx4938_ccfgptr->ccfg) | ||
119 | & TX4938_CCFG_PCI1DMD)) | ||
120 | tx4938_ccfg_set(TX4938_CCFG_PCI1_66); | ||
121 | mdelay(10); | ||
122 | /* clear PCIC1 reset */ | ||
123 | txx9_clear64(&tx4938_ccfgptr->clkctr, TX4938_CLKCTR_PCIC1RST); | ||
124 | tx4938_report_pci1clk(); | ||
125 | |||
126 | /* mem:64K(max), io:64K(max) (enough for ETH0,ETH1) */ | ||
127 | c = txx9_alloc_pci_controller(NULL, 0, 0x10000, 0, 0x10000); | ||
128 | register_pci_controller(c); | ||
129 | tx4927_pcic_setup(tx4938_pcic1ptr, c, 0); | ||
130 | } | ||
131 | #endif /* CONFIG_PCI */ | ||
132 | } | ||
133 | |||
134 | /* SPI support */ | ||
135 | |||
136 | /* chip select for SPI devices */ | ||
137 | #define SEEPROM1_CS 7 /* PIO7 */ | ||
138 | #define SEEPROM2_CS 0 /* IOC */ | ||
139 | #define SEEPROM3_CS 1 /* IOC */ | ||
140 | #define SRTC_CS 2 /* IOC */ | ||
141 | |||
142 | static int __init rbtx4938_ethaddr_init(void) | ||
143 | { | ||
144 | #ifdef CONFIG_PCI | ||
145 | unsigned char dat[17]; | ||
146 | unsigned char sum; | ||
147 | int i; | ||
148 | |||
149 | /* 0-3: "MAC\0", 4-9:eth0, 10-15:eth1, 16:sum */ | ||
150 | if (spi_eeprom_read(SEEPROM1_CS, 0, dat, sizeof(dat))) { | ||
151 | printk(KERN_ERR "seeprom: read error.\n"); | ||
152 | return -ENODEV; | ||
153 | } else { | ||
154 | if (strcmp(dat, "MAC") != 0) | ||
155 | printk(KERN_WARNING "seeprom: bad signature.\n"); | ||
156 | for (i = 0, sum = 0; i < sizeof(dat); i++) | ||
157 | sum += dat[i]; | ||
158 | if (sum) | ||
159 | printk(KERN_WARNING "seeprom: bad checksum.\n"); | ||
160 | } | ||
161 | for (i = 0; i < 2; i++) { | ||
162 | unsigned int id = | ||
163 | TXX9_IRQ_BASE + (i ? TX4938_IR_ETH1 : TX4938_IR_ETH0); | ||
164 | struct platform_device *pdev; | ||
165 | if (!(__raw_readq(&tx4938_ccfgptr->pcfg) & | ||
166 | (i ? TX4938_PCFG_ETH1_SEL : TX4938_PCFG_ETH0_SEL))) | ||
167 | continue; | ||
168 | pdev = platform_device_alloc("tc35815-mac", id); | ||
169 | if (!pdev || | ||
170 | platform_device_add_data(pdev, &dat[4 + 6 * i], 6) || | ||
171 | platform_device_add(pdev)) | ||
172 | platform_device_put(pdev); | ||
173 | } | ||
174 | #endif /* CONFIG_PCI */ | ||
175 | return 0; | ||
176 | } | ||
177 | |||
178 | static void __init rbtx4938_spi_setup(void) | ||
179 | { | ||
180 | /* set SPI_SEL */ | ||
181 | txx9_set64(&tx4938_ccfgptr->pcfg, TX4938_PCFG_SPI_SEL); | ||
182 | } | ||
183 | |||
184 | static struct resource rbtx4938_fpga_resource; | ||
185 | static struct resource tx4938_sdram_resource[4]; | ||
186 | static struct resource tx4938_sram_resource; | ||
187 | |||
188 | void __init tx4938_board_setup(void) | ||
189 | { | ||
190 | int i; | ||
191 | unsigned long divmode; | ||
192 | int cpuclk = 0; | ||
193 | unsigned long pcode = TX4938_REV_PCODE(); | ||
194 | |||
195 | ioport_resource.start = 0; | ||
196 | ioport_resource.end = 0xffffffff; | ||
197 | iomem_resource.start = 0; | ||
198 | iomem_resource.end = 0xffffffff; /* expand to 4GB */ | ||
199 | |||
200 | txx9_reg_res_init(pcode, TX4938_REG_BASE, | ||
201 | TX4938_REG_SIZE); | ||
202 | /* SDRAMC,EBUSC are configured by PROM */ | ||
203 | for (i = 0; i < 8; i++) { | ||
204 | if (!(TX4938_EBUSC_CR(i) & 0x8)) | ||
205 | continue; /* disabled */ | ||
206 | txx9_ce_res[i].start = (unsigned long)TX4938_EBUSC_BA(i); | ||
207 | txx9_ce_res[i].end = | ||
208 | txx9_ce_res[i].start + TX4938_EBUSC_SIZE(i) - 1; | ||
209 | request_resource(&iomem_resource, &txx9_ce_res[i]); | ||
210 | } | ||
211 | |||
212 | /* clocks */ | ||
213 | if (txx9_master_clock) { | ||
214 | u64 ccfg = ____raw_readq(&tx4938_ccfgptr->ccfg); | ||
215 | /* calculate gbus_clock and cpu_clock_freq from master_clock */ | ||
216 | divmode = (__u32)ccfg & TX4938_CCFG_DIVMODE_MASK; | ||
217 | switch (divmode) { | ||
218 | case TX4938_CCFG_DIVMODE_8: | ||
219 | case TX4938_CCFG_DIVMODE_10: | ||
220 | case TX4938_CCFG_DIVMODE_12: | ||
221 | case TX4938_CCFG_DIVMODE_16: | ||
222 | case TX4938_CCFG_DIVMODE_18: | ||
223 | txx9_gbus_clock = txx9_master_clock * 4; break; | ||
224 | default: | ||
225 | txx9_gbus_clock = txx9_master_clock; | ||
226 | } | ||
227 | switch (divmode) { | ||
228 | case TX4938_CCFG_DIVMODE_2: | ||
229 | case TX4938_CCFG_DIVMODE_8: | ||
230 | cpuclk = txx9_gbus_clock * 2; break; | ||
231 | case TX4938_CCFG_DIVMODE_2_5: | ||
232 | case TX4938_CCFG_DIVMODE_10: | ||
233 | cpuclk = txx9_gbus_clock * 5 / 2; break; | ||
234 | case TX4938_CCFG_DIVMODE_3: | ||
235 | case TX4938_CCFG_DIVMODE_12: | ||
236 | cpuclk = txx9_gbus_clock * 3; break; | ||
237 | case TX4938_CCFG_DIVMODE_4: | ||
238 | case TX4938_CCFG_DIVMODE_16: | ||
239 | cpuclk = txx9_gbus_clock * 4; break; | ||
240 | case TX4938_CCFG_DIVMODE_4_5: | ||
241 | case TX4938_CCFG_DIVMODE_18: | ||
242 | cpuclk = txx9_gbus_clock * 9 / 2; break; | ||
243 | } | ||
244 | txx9_cpu_clock = cpuclk; | ||
245 | } else { | ||
246 | u64 ccfg = ____raw_readq(&tx4938_ccfgptr->ccfg); | ||
247 | if (txx9_cpu_clock == 0) { | ||
248 | txx9_cpu_clock = 300000000; /* 300MHz */ | ||
249 | } | ||
250 | /* calculate gbus_clock and master_clock from cpu_clock_freq */ | ||
251 | cpuclk = txx9_cpu_clock; | ||
252 | divmode = (__u32)ccfg & TX4938_CCFG_DIVMODE_MASK; | ||
253 | switch (divmode) { | ||
254 | case TX4938_CCFG_DIVMODE_2: | ||
255 | case TX4938_CCFG_DIVMODE_8: | ||
256 | txx9_gbus_clock = cpuclk / 2; break; | ||
257 | case TX4938_CCFG_DIVMODE_2_5: | ||
258 | case TX4938_CCFG_DIVMODE_10: | ||
259 | txx9_gbus_clock = cpuclk * 2 / 5; break; | ||
260 | case TX4938_CCFG_DIVMODE_3: | ||
261 | case TX4938_CCFG_DIVMODE_12: | ||
262 | txx9_gbus_clock = cpuclk / 3; break; | ||
263 | case TX4938_CCFG_DIVMODE_4: | ||
264 | case TX4938_CCFG_DIVMODE_16: | ||
265 | txx9_gbus_clock = cpuclk / 4; break; | ||
266 | case TX4938_CCFG_DIVMODE_4_5: | ||
267 | case TX4938_CCFG_DIVMODE_18: | ||
268 | txx9_gbus_clock = cpuclk * 2 / 9; break; | ||
269 | } | ||
270 | switch (divmode) { | ||
271 | case TX4938_CCFG_DIVMODE_8: | ||
272 | case TX4938_CCFG_DIVMODE_10: | ||
273 | case TX4938_CCFG_DIVMODE_12: | ||
274 | case TX4938_CCFG_DIVMODE_16: | ||
275 | case TX4938_CCFG_DIVMODE_18: | ||
276 | txx9_master_clock = txx9_gbus_clock / 4; break; | ||
277 | default: | ||
278 | txx9_master_clock = txx9_gbus_clock; | ||
279 | } | ||
280 | } | ||
281 | /* change default value to udelay/mdelay take reasonable time */ | ||
282 | loops_per_jiffy = txx9_cpu_clock / HZ / 2; | ||
283 | |||
284 | /* CCFG */ | ||
285 | /* clear WatchDogReset,BusErrorOnWrite flag (W1C) */ | ||
286 | tx4938_ccfg_set(TX4938_CCFG_WDRST | TX4938_CCFG_BEOW); | ||
287 | /* do reset on watchdog */ | ||
288 | tx4938_ccfg_set(TX4938_CCFG_WR); | ||
289 | /* clear PCIC1 reset */ | ||
290 | txx9_clear64(&tx4938_ccfgptr->clkctr, TX4938_CLKCTR_PCIC1RST); | ||
291 | |||
292 | /* enable Timeout BusError */ | ||
293 | if (tx4938_ccfg_toeon) | ||
294 | tx4938_ccfg_set(TX4938_CCFG_TOE); | ||
295 | |||
296 | /* DMA selection */ | ||
297 | txx9_clear64(&tx4938_ccfgptr->pcfg, TX4938_PCFG_DMASEL_ALL); | ||
298 | |||
299 | /* Use external clock for external arbiter */ | ||
300 | if (!(____raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_PCIARB)) | ||
301 | txx9_clear64(&tx4938_ccfgptr->pcfg, TX4938_PCFG_PCICLKEN_ALL); | ||
302 | |||
303 | printk(KERN_INFO "%s -- %dMHz(M%dMHz) CRIR:%08x CCFG:%llx PCFG:%llx\n", | ||
304 | txx9_pcode_str, | ||
305 | (cpuclk + 500000) / 1000000, | ||
306 | (txx9_master_clock + 500000) / 1000000, | ||
307 | (__u32)____raw_readq(&tx4938_ccfgptr->crir), | ||
308 | (unsigned long long)____raw_readq(&tx4938_ccfgptr->ccfg), | ||
309 | (unsigned long long)____raw_readq(&tx4938_ccfgptr->pcfg)); | ||
310 | |||
311 | printk(KERN_INFO "%s SDRAMC --", txx9_pcode_str); | ||
312 | for (i = 0; i < 4; i++) { | ||
313 | unsigned long long cr = tx4938_sdramcptr->cr[i]; | ||
314 | unsigned long ram_base, ram_size; | ||
315 | if (!((unsigned long)cr & 0x00000400)) | ||
316 | continue; /* disabled */ | ||
317 | ram_base = (unsigned long)(cr >> 49) << 21; | ||
318 | ram_size = ((unsigned long)(cr >> 33) + 1) << 21; | ||
319 | if (ram_base >= 0x20000000) | ||
320 | continue; /* high memory (ignore) */ | ||
321 | printk(" CR%d:%016Lx", i, cr); | ||
322 | tx4938_sdram_resource[i].name = "SDRAM"; | ||
323 | tx4938_sdram_resource[i].start = ram_base; | ||
324 | tx4938_sdram_resource[i].end = ram_base + ram_size - 1; | ||
325 | tx4938_sdram_resource[i].flags = IORESOURCE_MEM; | ||
326 | request_resource(&iomem_resource, &tx4938_sdram_resource[i]); | ||
327 | } | ||
328 | printk(" TR:%09Lx\n", tx4938_sdramcptr->tr); | ||
329 | |||
330 | /* SRAM */ | ||
331 | if (tx4938_sramcptr->cr & 1) { | ||
332 | unsigned int size = 0x800; | ||
333 | unsigned long base = | ||
334 | (tx4938_sramcptr->cr >> (39-11)) & ~(size - 1); | ||
335 | tx4938_sram_resource.name = "SRAM"; | ||
336 | tx4938_sram_resource.start = base; | ||
337 | tx4938_sram_resource.end = base + size - 1; | ||
338 | tx4938_sram_resource.flags = IORESOURCE_MEM; | ||
339 | request_resource(&iomem_resource, &tx4938_sram_resource); | ||
340 | } | ||
341 | |||
342 | /* TMR */ | ||
343 | for (i = 0; i < TX4938_NR_TMR; i++) | ||
344 | txx9_tmr_init(TX4938_TMR_REG(i) & 0xfffffffffULL); | ||
345 | |||
346 | /* enable DMA */ | ||
347 | for (i = 0; i < 2; i++) | ||
348 | ____raw_writeq(TX4938_DMA_MCR_MSTEN, | ||
349 | (void __iomem *)(TX4938_DMA_REG(i) + 0x50)); | ||
350 | |||
351 | /* PIO */ | ||
352 | __raw_writel(0, &tx4938_pioptr->maskcpu); | ||
353 | __raw_writel(0, &tx4938_pioptr->maskext); | ||
354 | |||
355 | #ifdef CONFIG_PCI | ||
356 | txx9_alloc_pci_controller(&txx9_primary_pcic, 0, 0, 0, 0); | ||
357 | #endif | ||
358 | } | ||
359 | |||
360 | static void __init rbtx4938_time_init(void) | ||
361 | { | ||
362 | mips_hpt_frequency = txx9_cpu_clock / 2; | ||
363 | if (____raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_TINTDIS) | ||
364 | txx9_clockevent_init(TX4938_TMR_REG(0) & 0xfffffffffULL, | ||
365 | TXX9_IRQ_BASE + TX4938_IR_TMR(0), | ||
366 | txx9_gbus_clock / 2); | ||
367 | } | ||
368 | |||
369 | static void __init rbtx4938_mem_setup(void) | ||
370 | { | ||
371 | unsigned long long pcfg; | ||
372 | char *argptr; | ||
373 | |||
374 | iomem_resource.end = 0xffffffff; /* 4GB */ | ||
375 | |||
376 | if (txx9_master_clock == 0) | ||
377 | txx9_master_clock = 25000000; /* 25MHz */ | ||
378 | tx4938_board_setup(); | ||
379 | #ifndef CONFIG_PCI | ||
380 | set_io_port_base(RBTX4938_ETHER_BASE); | ||
381 | #endif | ||
382 | |||
383 | #ifdef CONFIG_SERIAL_TXX9 | ||
384 | { | ||
385 | extern int early_serial_txx9_setup(struct uart_port *port); | ||
386 | int i; | ||
387 | struct uart_port req; | ||
388 | for(i = 0; i < 2; i++) { | ||
389 | memset(&req, 0, sizeof(req)); | ||
390 | req.line = i; | ||
391 | req.iotype = UPIO_MEM; | ||
392 | req.membase = (char *)(0xff1ff300 + i * 0x100); | ||
393 | req.mapbase = 0xff1ff300 + i * 0x100; | ||
394 | req.irq = RBTX4938_IRQ_IRC_SIO(i); | ||
395 | req.flags |= UPF_BUGGY_UART /*HAVE_CTS_LINE*/; | ||
396 | req.uartclk = 50000000; | ||
397 | early_serial_txx9_setup(&req); | ||
398 | } | ||
399 | } | ||
400 | #ifdef CONFIG_SERIAL_TXX9_CONSOLE | ||
401 | argptr = prom_getcmdline(); | ||
402 | if (strstr(argptr, "console=") == NULL) { | ||
403 | strcat(argptr, " console=ttyS0,38400"); | ||
404 | } | ||
405 | #endif | ||
406 | #endif | ||
407 | |||
408 | #ifdef CONFIG_TOSHIBA_RBTX4938_MPLEX_PIO58_61 | ||
409 | printk("PIOSEL: disabling both ata and nand selection\n"); | ||
410 | local_irq_disable(); | ||
411 | txx9_clear64(&tx4938_ccfgptr->pcfg, | ||
412 | TX4938_PCFG_NDF_SEL | TX4938_PCFG_ATA_SEL); | ||
413 | #endif | ||
414 | |||
415 | #ifdef CONFIG_TOSHIBA_RBTX4938_MPLEX_NAND | ||
416 | printk("PIOSEL: enabling nand selection\n"); | ||
417 | txx9_set64(&tx4938_ccfgptr->pcfg, TX4938_PCFG_NDF_SEL); | ||
418 | txx9_clear64(&tx4938_ccfgptr->pcfg, TX4938_PCFG_ATA_SEL); | ||
419 | #endif | ||
420 | |||
421 | #ifdef CONFIG_TOSHIBA_RBTX4938_MPLEX_ATA | ||
422 | printk("PIOSEL: enabling ata selection\n"); | ||
423 | txx9_set64(&tx4938_ccfgptr->pcfg, TX4938_PCFG_ATA_SEL); | ||
424 | txx9_clear64(&tx4938_ccfgptr->pcfg, TX4938_PCFG_NDF_SEL); | ||
425 | #endif | ||
426 | |||
427 | #ifdef CONFIG_IP_PNP | ||
428 | argptr = prom_getcmdline(); | ||
429 | if (strstr(argptr, "ip=") == NULL) { | ||
430 | strcat(argptr, " ip=any"); | ||
431 | } | ||
432 | #endif | ||
433 | |||
434 | |||
435 | #ifdef CONFIG_FB | ||
436 | { | ||
437 | conswitchp = &dummy_con; | ||
438 | } | ||
439 | #endif | ||
440 | |||
441 | rbtx4938_spi_setup(); | ||
442 | pcfg = ____raw_readq(&tx4938_ccfgptr->pcfg); /* updated */ | ||
443 | /* fixup piosel */ | ||
444 | if ((pcfg & (TX4938_PCFG_ATA_SEL | TX4938_PCFG_NDF_SEL)) == | ||
445 | TX4938_PCFG_ATA_SEL) | ||
446 | writeb((readb(rbtx4938_piosel_addr) & 0x03) | 0x04, | ||
447 | rbtx4938_piosel_addr); | ||
448 | else if ((pcfg & (TX4938_PCFG_ATA_SEL | TX4938_PCFG_NDF_SEL)) == | ||
449 | TX4938_PCFG_NDF_SEL) | ||
450 | writeb((readb(rbtx4938_piosel_addr) & 0x03) | 0x08, | ||
451 | rbtx4938_piosel_addr); | ||
452 | else | ||
453 | writeb(readb(rbtx4938_piosel_addr) & ~(0x08 | 0x04), | ||
454 | rbtx4938_piosel_addr); | ||
455 | |||
456 | rbtx4938_fpga_resource.name = "FPGA Registers"; | ||
457 | rbtx4938_fpga_resource.start = CPHYSADDR(RBTX4938_FPGA_REG_ADDR); | ||
458 | rbtx4938_fpga_resource.end = CPHYSADDR(RBTX4938_FPGA_REG_ADDR) + 0xffff; | ||
459 | rbtx4938_fpga_resource.flags = IORESOURCE_MEM | IORESOURCE_BUSY; | ||
460 | if (request_resource(&iomem_resource, &rbtx4938_fpga_resource)) | ||
461 | printk("request resource for fpga failed\n"); | ||
462 | |||
463 | _machine_restart = rbtx4938_machine_restart; | ||
464 | _machine_halt = rbtx4938_machine_halt; | ||
465 | pm_power_off = rbtx4938_machine_power_off; | ||
466 | |||
467 | writeb(0xff, rbtx4938_led_addr); | ||
468 | printk(KERN_INFO "RBTX4938 --- FPGA(Rev %02x) DIPSW:%02x,%02x\n", | ||
469 | readb(rbtx4938_fpga_rev_addr), | ||
470 | readb(rbtx4938_dipsw_addr), readb(rbtx4938_bdipsw_addr)); | ||
471 | } | ||
472 | |||
473 | static int __init rbtx4938_ne_init(void) | ||
474 | { | ||
475 | struct resource res[] = { | ||
476 | { | ||
477 | .start = RBTX4938_RTL_8019_BASE, | ||
478 | .end = RBTX4938_RTL_8019_BASE + 0x20 - 1, | ||
479 | .flags = IORESOURCE_IO, | ||
480 | }, { | ||
481 | .start = RBTX4938_RTL_8019_IRQ, | ||
482 | .flags = IORESOURCE_IRQ, | ||
483 | } | ||
484 | }; | ||
485 | struct platform_device *dev = | ||
486 | platform_device_register_simple("ne", -1, | ||
487 | res, ARRAY_SIZE(res)); | ||
488 | return IS_ERR(dev) ? PTR_ERR(dev) : 0; | ||
489 | } | ||
490 | |||
491 | /* GPIO support */ | ||
492 | |||
493 | int gpio_to_irq(unsigned gpio) | ||
494 | { | ||
495 | return -EINVAL; | ||
496 | } | ||
497 | |||
498 | int irq_to_gpio(unsigned irq) | ||
499 | { | ||
500 | return -EINVAL; | ||
501 | } | ||
502 | |||
503 | static DEFINE_SPINLOCK(rbtx4938_spi_gpio_lock); | ||
504 | |||
505 | static void rbtx4938_spi_gpio_set(struct gpio_chip *chip, unsigned int offset, | ||
506 | int value) | ||
507 | { | ||
508 | u8 val; | ||
509 | unsigned long flags; | ||
510 | spin_lock_irqsave(&rbtx4938_spi_gpio_lock, flags); | ||
511 | val = readb(rbtx4938_spics_addr); | ||
512 | if (value) | ||
513 | val |= 1 << offset; | ||
514 | else | ||
515 | val &= ~(1 << offset); | ||
516 | writeb(val, rbtx4938_spics_addr); | ||
517 | mmiowb(); | ||
518 | spin_unlock_irqrestore(&rbtx4938_spi_gpio_lock, flags); | ||
519 | } | ||
520 | |||
521 | static int rbtx4938_spi_gpio_dir_out(struct gpio_chip *chip, | ||
522 | unsigned int offset, int value) | ||
523 | { | ||
524 | rbtx4938_spi_gpio_set(chip, offset, value); | ||
525 | return 0; | ||
526 | } | ||
527 | |||
528 | static struct gpio_chip rbtx4938_spi_gpio_chip = { | ||
529 | .set = rbtx4938_spi_gpio_set, | ||
530 | .direction_output = rbtx4938_spi_gpio_dir_out, | ||
531 | .label = "RBTX4938-SPICS", | ||
532 | .base = 16, | ||
533 | .ngpio = 3, | ||
534 | }; | ||
535 | |||
536 | /* SPI support */ | ||
537 | |||
538 | static void __init txx9_spi_init(unsigned long base, int irq) | ||
539 | { | ||
540 | struct resource res[] = { | ||
541 | { | ||
542 | .start = base, | ||
543 | .end = base + 0x20 - 1, | ||
544 | .flags = IORESOURCE_MEM, | ||
545 | }, { | ||
546 | .start = irq, | ||
547 | .flags = IORESOURCE_IRQ, | ||
548 | }, | ||
549 | }; | ||
550 | platform_device_register_simple("spi_txx9", 0, | ||
551 | res, ARRAY_SIZE(res)); | ||
552 | } | ||
553 | |||
554 | static int __init rbtx4938_spi_init(void) | ||
555 | { | ||
556 | struct spi_board_info srtc_info = { | ||
557 | .modalias = "rtc-rs5c348", | ||
558 | .max_speed_hz = 1000000, /* 1.0Mbps @ Vdd 2.0V */ | ||
559 | .bus_num = 0, | ||
560 | .chip_select = 16 + SRTC_CS, | ||
561 | /* Mode 1 (High-Active, Shift-Then-Sample), High Avtive CS */ | ||
562 | .mode = SPI_MODE_1 | SPI_CS_HIGH, | ||
563 | }; | ||
564 | spi_register_board_info(&srtc_info, 1); | ||
565 | spi_eeprom_register(SEEPROM1_CS); | ||
566 | spi_eeprom_register(16 + SEEPROM2_CS); | ||
567 | spi_eeprom_register(16 + SEEPROM3_CS); | ||
568 | gpio_request(16 + SRTC_CS, "rtc-rs5c348"); | ||
569 | gpio_direction_output(16 + SRTC_CS, 0); | ||
570 | gpio_request(SEEPROM1_CS, "seeprom1"); | ||
571 | gpio_direction_output(SEEPROM1_CS, 1); | ||
572 | gpio_request(16 + SEEPROM2_CS, "seeprom2"); | ||
573 | gpio_direction_output(16 + SEEPROM2_CS, 1); | ||
574 | gpio_request(16 + SEEPROM3_CS, "seeprom3"); | ||
575 | gpio_direction_output(16 + SEEPROM3_CS, 1); | ||
576 | txx9_spi_init(TX4938_SPI_REG & 0xfffffffffULL, RBTX4938_IRQ_IRC_SPI); | ||
577 | return 0; | ||
578 | } | ||
579 | |||
580 | static void __init rbtx4938_arch_init(void) | ||
581 | { | ||
582 | txx9_gpio_init(TX4938_PIO_REG & 0xfffffffffULL, 0, 16); | ||
583 | gpiochip_add(&rbtx4938_spi_gpio_chip); | ||
584 | rbtx4938_pci_setup(); | ||
585 | rbtx4938_spi_init(); | ||
586 | } | ||
587 | |||
588 | /* Watchdog support */ | ||
589 | |||
590 | static int __init txx9_wdt_init(unsigned long base) | ||
591 | { | ||
592 | struct resource res = { | ||
593 | .start = base, | ||
594 | .end = base + 0x100 - 1, | ||
595 | .flags = IORESOURCE_MEM, | ||
596 | }; | ||
597 | struct platform_device *dev = | ||
598 | platform_device_register_simple("txx9wdt", -1, &res, 1); | ||
599 | return IS_ERR(dev) ? PTR_ERR(dev) : 0; | ||
600 | } | ||
601 | |||
602 | static int __init rbtx4938_wdt_init(void) | ||
603 | { | ||
604 | return txx9_wdt_init(TX4938_TMR_REG(2) & 0xfffffffffULL); | ||
605 | } | ||
606 | |||
607 | static void __init rbtx4938_device_init(void) | ||
608 | { | ||
609 | rbtx4938_ethaddr_init(); | ||
610 | rbtx4938_ne_init(); | ||
611 | rbtx4938_wdt_init(); | ||
612 | } | ||
613 | |||
614 | struct txx9_board_vec rbtx4938_vec __initdata = { | ||
615 | .system = "Toshiba RBTX4938", | ||
616 | .prom_init = rbtx4938_prom_init, | ||
617 | .mem_setup = rbtx4938_mem_setup, | ||
618 | .irq_setup = rbtx4938_irq_setup, | ||
619 | .time_init = rbtx4938_time_init, | ||
620 | .device_init = rbtx4938_device_init, | ||
621 | .arch_init = rbtx4938_arch_init, | ||
622 | #ifdef CONFIG_PCI | ||
623 | .pci_map_irq = rbtx4938_pci_map_irq, | ||
624 | #endif | ||
625 | }; | ||