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 | }; | ||
