diff options
Diffstat (limited to 'arch/mips/txx9/rbtx4938/setup.c')
-rw-r--r-- | arch/mips/txx9/rbtx4938/setup.c | 372 |
1 files changed, 372 insertions, 0 deletions
diff --git a/arch/mips/txx9/rbtx4938/setup.c b/arch/mips/txx9/rbtx4938/setup.c new file mode 100644 index 000000000..e68eb2e7c --- /dev/null +++ b/arch/mips/txx9/rbtx4938/setup.c | |||
@@ -0,0 +1,372 @@ | |||
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/platform_device.h> | ||
17 | #include <linux/gpio/driver.h> | ||
18 | #include <linux/gpio.h> | ||
19 | #include <linux/mtd/physmap.h> | ||
20 | |||
21 | #include <asm/reboot.h> | ||
22 | #include <asm/io.h> | ||
23 | #include <asm/txx9/generic.h> | ||
24 | #include <asm/txx9/pci.h> | ||
25 | #include <asm/txx9/rbtx4938.h> | ||
26 | #include <linux/spi/spi.h> | ||
27 | #include <asm/txx9/spi.h> | ||
28 | #include <asm/txx9pio.h> | ||
29 | |||
30 | static void rbtx4938_machine_restart(char *command) | ||
31 | { | ||
32 | local_irq_disable(); | ||
33 | writeb(1, rbtx4938_softresetlock_addr); | ||
34 | writeb(1, rbtx4938_sfvol_addr); | ||
35 | writeb(1, rbtx4938_softreset_addr); | ||
36 | /* fallback */ | ||
37 | (*_machine_halt)(); | ||
38 | } | ||
39 | |||
40 | static void __init rbtx4938_pci_setup(void) | ||
41 | { | ||
42 | #ifdef CONFIG_PCI | ||
43 | int extarb = !(__raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_PCIARB); | ||
44 | struct pci_controller *c = &txx9_primary_pcic; | ||
45 | |||
46 | register_pci_controller(c); | ||
47 | |||
48 | if (__raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_PCI66) | ||
49 | txx9_pci_option = | ||
50 | (txx9_pci_option & ~TXX9_PCI_OPT_CLK_MASK) | | ||
51 | TXX9_PCI_OPT_CLK_66; /* already configured */ | ||
52 | |||
53 | /* Reset PCI Bus */ | ||
54 | writeb(0, rbtx4938_pcireset_addr); | ||
55 | /* Reset PCIC */ | ||
56 | txx9_set64(&tx4938_ccfgptr->clkctr, TX4938_CLKCTR_PCIRST); | ||
57 | if ((txx9_pci_option & TXX9_PCI_OPT_CLK_MASK) == | ||
58 | TXX9_PCI_OPT_CLK_66) | ||
59 | tx4938_pciclk66_setup(); | ||
60 | mdelay(10); | ||
61 | /* clear PCIC reset */ | ||
62 | txx9_clear64(&tx4938_ccfgptr->clkctr, TX4938_CLKCTR_PCIRST); | ||
63 | writeb(1, rbtx4938_pcireset_addr); | ||
64 | iob(); | ||
65 | |||
66 | tx4938_report_pciclk(); | ||
67 | tx4927_pcic_setup(tx4938_pcicptr, c, extarb); | ||
68 | if ((txx9_pci_option & TXX9_PCI_OPT_CLK_MASK) == | ||
69 | TXX9_PCI_OPT_CLK_AUTO && | ||
70 | txx9_pci66_check(c, 0, 0)) { | ||
71 | /* Reset PCI Bus */ | ||
72 | writeb(0, rbtx4938_pcireset_addr); | ||
73 | /* Reset PCIC */ | ||
74 | txx9_set64(&tx4938_ccfgptr->clkctr, TX4938_CLKCTR_PCIRST); | ||
75 | tx4938_pciclk66_setup(); | ||
76 | mdelay(10); | ||
77 | /* clear PCIC reset */ | ||
78 | txx9_clear64(&tx4938_ccfgptr->clkctr, TX4938_CLKCTR_PCIRST); | ||
79 | writeb(1, rbtx4938_pcireset_addr); | ||
80 | iob(); | ||
81 | /* Reinitialize PCIC */ | ||
82 | tx4938_report_pciclk(); | ||
83 | tx4927_pcic_setup(tx4938_pcicptr, c, extarb); | ||
84 | } | ||
85 | |||
86 | if (__raw_readq(&tx4938_ccfgptr->pcfg) & | ||
87 | (TX4938_PCFG_ETH0_SEL|TX4938_PCFG_ETH1_SEL)) { | ||
88 | /* Reset PCIC1 */ | ||
89 | txx9_set64(&tx4938_ccfgptr->clkctr, TX4938_CLKCTR_PCIC1RST); | ||
90 | /* PCI1DMD==0 => PCI1CLK==GBUSCLK/2 => PCI66 */ | ||
91 | if (!(__raw_readq(&tx4938_ccfgptr->ccfg) | ||
92 | & TX4938_CCFG_PCI1DMD)) | ||
93 | tx4938_ccfg_set(TX4938_CCFG_PCI1_66); | ||
94 | mdelay(10); | ||
95 | /* clear PCIC1 reset */ | ||
96 | txx9_clear64(&tx4938_ccfgptr->clkctr, TX4938_CLKCTR_PCIC1RST); | ||
97 | tx4938_report_pci1clk(); | ||
98 | |||
99 | /* mem:64K(max), io:64K(max) (enough for ETH0,ETH1) */ | ||
100 | c = txx9_alloc_pci_controller(NULL, 0, 0x10000, 0, 0x10000); | ||
101 | register_pci_controller(c); | ||
102 | tx4927_pcic_setup(tx4938_pcic1ptr, c, 0); | ||
103 | } | ||
104 | tx4938_setup_pcierr_irq(); | ||
105 | #endif /* CONFIG_PCI */ | ||
106 | } | ||
107 | |||
108 | /* SPI support */ | ||
109 | |||
110 | /* chip select for SPI devices */ | ||
111 | #define SEEPROM1_CS 7 /* PIO7 */ | ||
112 | #define SEEPROM2_CS 0 /* IOC */ | ||
113 | #define SEEPROM3_CS 1 /* IOC */ | ||
114 | #define SRTC_CS 2 /* IOC */ | ||
115 | #define SPI_BUSNO 0 | ||
116 | |||
117 | static int __init rbtx4938_ethaddr_init(void) | ||
118 | { | ||
119 | #ifdef CONFIG_PCI | ||
120 | unsigned char dat[17]; | ||
121 | unsigned char sum; | ||
122 | int i; | ||
123 | |||
124 | /* 0-3: "MAC\0", 4-9:eth0, 10-15:eth1, 16:sum */ | ||
125 | if (spi_eeprom_read(SPI_BUSNO, SEEPROM1_CS, 0, dat, sizeof(dat))) { | ||
126 | pr_err("seeprom: read error.\n"); | ||
127 | return -ENODEV; | ||
128 | } else { | ||
129 | if (strcmp(dat, "MAC") != 0) | ||
130 | pr_warn("seeprom: bad signature.\n"); | ||
131 | for (i = 0, sum = 0; i < sizeof(dat); i++) | ||
132 | sum += dat[i]; | ||
133 | if (sum) | ||
134 | pr_warn("seeprom: bad checksum.\n"); | ||
135 | } | ||
136 | tx4938_ethaddr_init(&dat[4], &dat[4 + 6]); | ||
137 | #endif /* CONFIG_PCI */ | ||
138 | return 0; | ||
139 | } | ||
140 | |||
141 | static void __init rbtx4938_spi_setup(void) | ||
142 | { | ||
143 | /* set SPI_SEL */ | ||
144 | txx9_set64(&tx4938_ccfgptr->pcfg, TX4938_PCFG_SPI_SEL); | ||
145 | } | ||
146 | |||
147 | static struct resource rbtx4938_fpga_resource; | ||
148 | |||
149 | static void __init rbtx4938_time_init(void) | ||
150 | { | ||
151 | tx4938_time_init(0); | ||
152 | } | ||
153 | |||
154 | static void __init rbtx4938_mem_setup(void) | ||
155 | { | ||
156 | unsigned long long pcfg; | ||
157 | |||
158 | if (txx9_master_clock == 0) | ||
159 | txx9_master_clock = 25000000; /* 25MHz */ | ||
160 | |||
161 | tx4938_setup(); | ||
162 | |||
163 | #ifdef CONFIG_PCI | ||
164 | txx9_alloc_pci_controller(&txx9_primary_pcic, 0, 0, 0, 0); | ||
165 | txx9_board_pcibios_setup = tx4927_pcibios_setup; | ||
166 | #else | ||
167 | set_io_port_base(RBTX4938_ETHER_BASE); | ||
168 | #endif | ||
169 | |||
170 | tx4938_sio_init(7372800, 0); | ||
171 | |||
172 | #ifdef CONFIG_TOSHIBA_RBTX4938_MPLEX_PIO58_61 | ||
173 | pr_info("PIOSEL: disabling both ATA and NAND selection\n"); | ||
174 | txx9_clear64(&tx4938_ccfgptr->pcfg, | ||
175 | TX4938_PCFG_NDF_SEL | TX4938_PCFG_ATA_SEL); | ||
176 | #endif | ||
177 | |||
178 | #ifdef CONFIG_TOSHIBA_RBTX4938_MPLEX_NAND | ||
179 | pr_info("PIOSEL: enabling NAND selection\n"); | ||
180 | txx9_set64(&tx4938_ccfgptr->pcfg, TX4938_PCFG_NDF_SEL); | ||
181 | txx9_clear64(&tx4938_ccfgptr->pcfg, TX4938_PCFG_ATA_SEL); | ||
182 | #endif | ||
183 | |||
184 | #ifdef CONFIG_TOSHIBA_RBTX4938_MPLEX_ATA | ||
185 | pr_info("PIOSEL: enabling ATA selection\n"); | ||
186 | txx9_set64(&tx4938_ccfgptr->pcfg, TX4938_PCFG_ATA_SEL); | ||
187 | txx9_clear64(&tx4938_ccfgptr->pcfg, TX4938_PCFG_NDF_SEL); | ||
188 | #endif | ||
189 | |||
190 | #ifdef CONFIG_TOSHIBA_RBTX4938_MPLEX_KEEP | ||
191 | pcfg = ____raw_readq(&tx4938_ccfgptr->pcfg); | ||
192 | pr_info("PIOSEL: NAND %s, ATA %s\n", | ||
193 | (pcfg & TX4938_PCFG_NDF_SEL) ? "enabled" : "disabled", | ||
194 | (pcfg & TX4938_PCFG_ATA_SEL) ? "enabled" : "disabled"); | ||
195 | #endif | ||
196 | |||
197 | rbtx4938_spi_setup(); | ||
198 | pcfg = ____raw_readq(&tx4938_ccfgptr->pcfg); /* updated */ | ||
199 | /* fixup piosel */ | ||
200 | if ((pcfg & (TX4938_PCFG_ATA_SEL | TX4938_PCFG_NDF_SEL)) == | ||
201 | TX4938_PCFG_ATA_SEL) | ||
202 | writeb((readb(rbtx4938_piosel_addr) & 0x03) | 0x04, | ||
203 | rbtx4938_piosel_addr); | ||
204 | else if ((pcfg & (TX4938_PCFG_ATA_SEL | TX4938_PCFG_NDF_SEL)) == | ||
205 | TX4938_PCFG_NDF_SEL) | ||
206 | writeb((readb(rbtx4938_piosel_addr) & 0x03) | 0x08, | ||
207 | rbtx4938_piosel_addr); | ||
208 | else | ||
209 | writeb(readb(rbtx4938_piosel_addr) & ~(0x08 | 0x04), | ||
210 | rbtx4938_piosel_addr); | ||
211 | |||
212 | rbtx4938_fpga_resource.name = "FPGA Registers"; | ||
213 | rbtx4938_fpga_resource.start = CPHYSADDR(RBTX4938_FPGA_REG_ADDR); | ||
214 | rbtx4938_fpga_resource.end = CPHYSADDR(RBTX4938_FPGA_REG_ADDR) + 0xffff; | ||
215 | rbtx4938_fpga_resource.flags = IORESOURCE_MEM | IORESOURCE_BUSY; | ||
216 | if (request_resource(&txx9_ce_res[2], &rbtx4938_fpga_resource)) | ||
217 | pr_err("request resource for fpga failed\n"); | ||
218 | |||
219 | _machine_restart = rbtx4938_machine_restart; | ||
220 | |||
221 | writeb(0xff, rbtx4938_led_addr); | ||
222 | pr_info("RBTX4938 --- FPGA(Rev %02x) DIPSW:%02x,%02x\n", | ||
223 | readb(rbtx4938_fpga_rev_addr), | ||
224 | readb(rbtx4938_dipsw_addr), readb(rbtx4938_bdipsw_addr)); | ||
225 | } | ||
226 | |||
227 | static void __init rbtx4938_ne_init(void) | ||
228 | { | ||
229 | struct resource res[] = { | ||
230 | { | ||
231 | .start = RBTX4938_RTL_8019_BASE, | ||
232 | .end = RBTX4938_RTL_8019_BASE + 0x20 - 1, | ||
233 | .flags = IORESOURCE_IO, | ||
234 | }, { | ||
235 | .start = RBTX4938_RTL_8019_IRQ, | ||
236 | .flags = IORESOURCE_IRQ, | ||
237 | } | ||
238 | }; | ||
239 | platform_device_register_simple("ne", -1, res, ARRAY_SIZE(res)); | ||
240 | } | ||
241 | |||
242 | static DEFINE_SPINLOCK(rbtx4938_spi_gpio_lock); | ||
243 | |||
244 | static void rbtx4938_spi_gpio_set(struct gpio_chip *chip, unsigned int offset, | ||
245 | int value) | ||
246 | { | ||
247 | u8 val; | ||
248 | unsigned long flags; | ||
249 | spin_lock_irqsave(&rbtx4938_spi_gpio_lock, flags); | ||
250 | val = readb(rbtx4938_spics_addr); | ||
251 | if (value) | ||
252 | val |= 1 << offset; | ||
253 | else | ||
254 | val &= ~(1 << offset); | ||
255 | writeb(val, rbtx4938_spics_addr); | ||
256 | mmiowb(); | ||
257 | spin_unlock_irqrestore(&rbtx4938_spi_gpio_lock, flags); | ||
258 | } | ||
259 | |||
260 | static int rbtx4938_spi_gpio_dir_out(struct gpio_chip *chip, | ||
261 | unsigned int offset, int value) | ||
262 | { | ||
263 | rbtx4938_spi_gpio_set(chip, offset, value); | ||
264 | return 0; | ||
265 | } | ||
266 | |||
267 | static struct gpio_chip rbtx4938_spi_gpio_chip = { | ||
268 | .set = rbtx4938_spi_gpio_set, | ||
269 | .direction_output = rbtx4938_spi_gpio_dir_out, | ||
270 | .label = "RBTX4938-SPICS", | ||
271 | .base = 16, | ||
272 | .ngpio = 3, | ||
273 | }; | ||
274 | |||
275 | static int __init rbtx4938_spi_init(void) | ||
276 | { | ||
277 | struct spi_board_info srtc_info = { | ||
278 | .modalias = "rtc-rs5c348", | ||
279 | .max_speed_hz = 1000000, /* 1.0Mbps @ Vdd 2.0V */ | ||
280 | .bus_num = 0, | ||
281 | .chip_select = 16 + SRTC_CS, | ||
282 | /* Mode 1 (High-Active, Shift-Then-Sample), High Avtive CS */ | ||
283 | .mode = SPI_MODE_1 | SPI_CS_HIGH, | ||
284 | }; | ||
285 | spi_register_board_info(&srtc_info, 1); | ||
286 | spi_eeprom_register(SPI_BUSNO, SEEPROM1_CS, 128); | ||
287 | spi_eeprom_register(SPI_BUSNO, 16 + SEEPROM2_CS, 128); | ||
288 | spi_eeprom_register(SPI_BUSNO, 16 + SEEPROM3_CS, 128); | ||
289 | gpio_request(16 + SRTC_CS, "rtc-rs5c348"); | ||
290 | gpio_direction_output(16 + SRTC_CS, 0); | ||
291 | gpio_request(SEEPROM1_CS, "seeprom1"); | ||
292 | gpio_direction_output(SEEPROM1_CS, 1); | ||
293 | gpio_request(16 + SEEPROM2_CS, "seeprom2"); | ||
294 | gpio_direction_output(16 + SEEPROM2_CS, 1); | ||
295 | gpio_request(16 + SEEPROM3_CS, "seeprom3"); | ||
296 | gpio_direction_output(16 + SEEPROM3_CS, 1); | ||
297 | tx4938_spi_init(SPI_BUSNO); | ||
298 | return 0; | ||
299 | } | ||
300 | |||
301 | static void __init rbtx4938_mtd_init(void) | ||
302 | { | ||
303 | struct physmap_flash_data pdata = { | ||
304 | .width = 4, | ||
305 | }; | ||
306 | |||
307 | switch (readb(rbtx4938_bdipsw_addr) & 7) { | ||
308 | case 0: | ||
309 | /* Boot */ | ||
310 | txx9_physmap_flash_init(0, 0x1fc00000, 0x400000, &pdata); | ||
311 | /* System */ | ||
312 | txx9_physmap_flash_init(1, 0x1e000000, 0x1000000, &pdata); | ||
313 | break; | ||
314 | case 1: | ||
315 | /* System */ | ||
316 | txx9_physmap_flash_init(0, 0x1f000000, 0x1000000, &pdata); | ||
317 | /* Boot */ | ||
318 | txx9_physmap_flash_init(1, 0x1ec00000, 0x400000, &pdata); | ||
319 | break; | ||
320 | case 2: | ||
321 | /* Ext */ | ||
322 | txx9_physmap_flash_init(0, 0x1f000000, 0x1000000, &pdata); | ||
323 | /* System */ | ||
324 | txx9_physmap_flash_init(1, 0x1e000000, 0x1000000, &pdata); | ||
325 | /* Boot */ | ||
326 | txx9_physmap_flash_init(2, 0x1dc00000, 0x400000, &pdata); | ||
327 | break; | ||
328 | case 3: | ||
329 | /* Boot */ | ||
330 | txx9_physmap_flash_init(1, 0x1bc00000, 0x400000, &pdata); | ||
331 | /* System */ | ||
332 | txx9_physmap_flash_init(2, 0x1a000000, 0x1000000, &pdata); | ||
333 | break; | ||
334 | } | ||
335 | } | ||
336 | |||
337 | static void __init rbtx4938_arch_init(void) | ||
338 | { | ||
339 | txx9_gpio_init(TX4938_PIO_REG & 0xfffffffffULL, 0, TX4938_NUM_PIO); | ||
340 | gpiochip_add_data(&rbtx4938_spi_gpio_chip, NULL); | ||
341 | rbtx4938_pci_setup(); | ||
342 | rbtx4938_spi_init(); | ||
343 | } | ||
344 | |||
345 | static void __init rbtx4938_device_init(void) | ||
346 | { | ||
347 | rbtx4938_ethaddr_init(); | ||
348 | rbtx4938_ne_init(); | ||
349 | tx4938_wdt_init(); | ||
350 | rbtx4938_mtd_init(); | ||
351 | /* TC58DVM82A1FT: tDH=10ns, tWP=tRP=tREADID=35ns */ | ||
352 | tx4938_ndfmc_init(10, 35); | ||
353 | tx4938_ata_init(RBTX4938_IRQ_IOC_ATA, 0, 1); | ||
354 | tx4938_dmac_init(0, 2); | ||
355 | tx4938_aclc_init(); | ||
356 | platform_device_register_simple("txx9aclc-generic", -1, NULL, 0); | ||
357 | tx4938_sramc_init(); | ||
358 | txx9_iocled_init(RBTX4938_LED_ADDR - IO_BASE, -1, 8, 1, "green", NULL); | ||
359 | } | ||
360 | |||
361 | struct txx9_board_vec rbtx4938_vec __initdata = { | ||
362 | .system = "Toshiba RBTX4938", | ||
363 | .prom_init = rbtx4938_prom_init, | ||
364 | .mem_setup = rbtx4938_mem_setup, | ||
365 | .irq_setup = rbtx4938_irq_setup, | ||
366 | .time_init = rbtx4938_time_init, | ||
367 | .device_init = rbtx4938_device_init, | ||
368 | .arch_init = rbtx4938_arch_init, | ||
369 | #ifdef CONFIG_PCI | ||
370 | .pci_map_irq = rbtx4938_pci_map_irq, | ||
371 | #endif | ||
372 | }; | ||