Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame^] | 1 | /* |
| 2 | * arch/mips/ddb5476/setup.c -- NEC DDB Vrc-5476 setup routines |
| 3 | * |
| 4 | * Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com> |
| 5 | * Sony Software Development Center Europe (SDCE), Brussels |
| 6 | */ |
| 7 | #include <linux/init.h> |
| 8 | #include <linux/kbd_ll.h> |
| 9 | #include <linux/kernel.h> |
| 10 | #include <linux/kdev_t.h> |
| 11 | #include <linux/types.h> |
| 12 | #include <linux/sched.h> |
| 13 | #include <linux/pci.h> |
| 14 | |
| 15 | #include <asm/addrspace.h> |
| 16 | #include <asm/bcache.h> |
| 17 | #include <asm/irq.h> |
| 18 | #include <asm/reboot.h> |
| 19 | #include <asm/gdb-stub.h> |
| 20 | #include <asm/time.h> |
| 21 | #include <asm/debug.h> |
| 22 | #include <asm/traps.h> |
| 23 | |
| 24 | #include <asm/ddb5xxx/ddb5xxx.h> |
| 25 | |
| 26 | // #define USE_CPU_COUNTER_TIMER /* whether we use cpu counter */ |
| 27 | |
| 28 | #ifdef USE_CPU_COUNTER_TIMER |
| 29 | |
| 30 | #define CPU_COUNTER_FREQUENCY 83000000 |
| 31 | #else |
| 32 | /* otherwise we use general purpose timer */ |
| 33 | #define TIMER_FREQUENCY 83000000 |
| 34 | #define TIMER_BASE DDB_T2CTRL |
| 35 | #define TIMER_IRQ (VRC5476_IRQ_BASE + VRC5476_IRQ_GPT) |
| 36 | #endif |
| 37 | |
| 38 | static void (*back_to_prom) (void) = (void (*)(void)) 0xbfc00000; |
| 39 | |
| 40 | static void ddb_machine_restart(char *command) |
| 41 | { |
| 42 | u32 t; |
| 43 | |
| 44 | /* PCI cold reset */ |
| 45 | t = ddb_in32(DDB_PCICTRL + 4); |
| 46 | t |= 0x40000000; |
| 47 | ddb_out32(DDB_PCICTRL + 4, t); |
| 48 | /* CPU cold reset */ |
| 49 | t = ddb_in32(DDB_CPUSTAT); |
| 50 | t |= 1; |
| 51 | ddb_out32(DDB_CPUSTAT, t); |
| 52 | /* Call the PROM */ |
| 53 | back_to_prom(); |
| 54 | } |
| 55 | |
| 56 | static void ddb_machine_halt(void) |
| 57 | { |
| 58 | printk(KERN_NOTICE "DDB Vrc-5476 halted.\n"); |
| 59 | while (1); |
| 60 | } |
| 61 | |
| 62 | static void ddb_machine_power_off(void) |
| 63 | { |
| 64 | printk(KERN_NOTICE "DDB Vrc-5476 halted. Please turn off the power.\n"); |
| 65 | while (1); |
| 66 | } |
| 67 | |
| 68 | extern void rtc_ds1386_init(unsigned long base); |
| 69 | |
| 70 | static void __init ddb_time_init(void) |
| 71 | { |
| 72 | #if defined(USE_CPU_COUNTER_TIMER) |
| 73 | mips_hpt_frequency = CPU_COUNTER_FREQUENCY; |
| 74 | #endif |
| 75 | |
| 76 | /* we have ds1396 RTC chip */ |
| 77 | rtc_ds1386_init(KSEG1ADDR(DDB_PCI_MEM_BASE)); |
| 78 | } |
| 79 | |
| 80 | |
| 81 | extern int setup_irq(unsigned int irq, struct irqaction *irqaction); |
| 82 | static void __init ddb_timer_setup(struct irqaction *irq) |
| 83 | { |
| 84 | #if defined(USE_CPU_COUNTER_TIMER) |
| 85 | |
| 86 | unsigned int count; |
| 87 | |
| 88 | /* we are using the cpu counter for timer interrupts */ |
| 89 | setup_irq(CPU_IRQ_BASE + 7, irq); |
| 90 | |
| 91 | /* to generate the first timer interrupt */ |
| 92 | count = read_c0_count(); |
| 93 | write_c0_compare(count + 1000); |
| 94 | |
| 95 | #else |
| 96 | |
| 97 | ddb_out32(TIMER_BASE, TIMER_FREQUENCY/HZ); |
| 98 | ddb_out32(TIMER_BASE+4, 0x1); /* enable timer */ |
| 99 | setup_irq(TIMER_IRQ, irq); |
| 100 | #endif |
| 101 | } |
| 102 | |
| 103 | static struct { |
| 104 | struct resource dma1; |
| 105 | struct resource timer; |
| 106 | struct resource rtc; |
| 107 | struct resource dma_page_reg; |
| 108 | struct resource dma2; |
| 109 | } ddb5476_ioport = { |
| 110 | { |
| 111 | "dma1", 0x00, 0x1f, IORESOURCE_BUSY}, { |
| 112 | "timer", 0x40, 0x5f, IORESOURCE_BUSY}, { |
| 113 | "rtc", 0x70, 0x7f, IORESOURCE_BUSY}, { |
| 114 | "dma page reg", 0x80, 0x8f, IORESOURCE_BUSY}, { |
| 115 | "dma2", 0xc0, 0xdf, IORESOURCE_BUSY} |
| 116 | }; |
| 117 | |
| 118 | static struct { |
| 119 | struct resource nile4; |
| 120 | } ddb5476_iomem = { |
| 121 | { "Nile 4", DDB_BASE, DDB_BASE + DDB_SIZE - 1, IORESOURCE_BUSY} |
| 122 | }; |
| 123 | |
| 124 | |
| 125 | static void ddb5476_board_init(void); |
| 126 | |
| 127 | static void __init ddb5476_setup(void) |
| 128 | { |
| 129 | set_io_port_base(KSEG1ADDR(DDB_PCI_IO_BASE)); |
| 130 | |
| 131 | board_time_init = ddb_time_init; |
| 132 | board_timer_setup = ddb_timer_setup; |
| 133 | |
| 134 | _machine_restart = ddb_machine_restart; |
| 135 | _machine_halt = ddb_machine_halt; |
| 136 | _machine_power_off = ddb_machine_power_off; |
| 137 | |
| 138 | /* request io port/mem resources */ |
| 139 | if (request_resource(&ioport_resource, &ddb5476_ioport.dma1) || |
| 140 | request_resource(&ioport_resource, &ddb5476_ioport.timer) || |
| 141 | request_resource(&ioport_resource, &ddb5476_ioport.rtc) || |
| 142 | request_resource(&ioport_resource, |
| 143 | &ddb5476_ioport.dma_page_reg) |
| 144 | || request_resource(&ioport_resource, &ddb5476_ioport.dma2) |
| 145 | || request_resource(&iomem_resource, &ddb5476_iomem.nile4)) { |
| 146 | printk |
| 147 | ("ddb_setup - requesting oo port resources failed.\n"); |
| 148 | for (;;); |
| 149 | } |
| 150 | |
| 151 | /* Reboot on panic */ |
| 152 | panic_timeout = 180; |
| 153 | |
| 154 | /* [jsun] we need to set BAR0 so that SDRAM 0 appears at 0x0 in PCI */ |
| 155 | /* *(long*)0xbfa00218 = 0x8; */ |
| 156 | |
| 157 | /* board initialization stuff */ |
| 158 | ddb5476_board_init(); |
| 159 | } |
| 160 | |
| 161 | early_initcall(ddb5476_setup); |
| 162 | |
| 163 | /* |
| 164 | * We don't trust bios. We essentially does hardware re-initialization |
| 165 | * as complete as possible, as far as we know we can safely do. |
| 166 | */ |
| 167 | static void ddb5476_board_init(void) |
| 168 | { |
| 169 | /* ----------- setup PDARs ------------ */ |
| 170 | /* check SDRAM0, whether we are on MEM bus does not matter */ |
| 171 | db_assert((ddb_in32(DDB_SDRAM0) & 0xffffffef) == |
| 172 | ddb_calc_pdar(DDB_SDRAM_BASE, DDB_SDRAM_SIZE, 32, 0, 1)); |
| 173 | |
| 174 | /* SDRAM1 should be turned off. What is this for anyway ? */ |
| 175 | db_assert( (ddb_in32(DDB_SDRAM1) & 0xf) == 0); |
| 176 | |
| 177 | /* flash 1&2, DDB status, DDB control */ |
| 178 | ddb_set_pdar(DDB_DCS2, DDB_DCS2_BASE, DDB_DCS2_SIZE, 16, 0, 0); |
| 179 | ddb_set_pdar(DDB_DCS3, DDB_DCS3_BASE, DDB_DCS3_SIZE, 16, 0, 0); |
| 180 | ddb_set_pdar(DDB_DCS4, DDB_DCS4_BASE, DDB_DCS4_SIZE, 8, 0, 0); |
| 181 | ddb_set_pdar(DDB_DCS5, DDB_DCS5_BASE, DDB_DCS5_SIZE, 8, 0, 0); |
| 182 | |
| 183 | /* shut off other pdar so they don't accidentally get into the way */ |
| 184 | ddb_set_pdar(DDB_DCS6, 0xffffffff, 0, 32, 0, 0); |
| 185 | ddb_set_pdar(DDB_DCS7, 0xffffffff, 0, 32, 0, 0); |
| 186 | ddb_set_pdar(DDB_DCS8, 0xffffffff, 0, 32, 0, 0); |
| 187 | |
| 188 | /* verify VRC5477 base addr */ |
| 189 | /* don't care about some details */ |
| 190 | db_assert((ddb_in32(DDB_INTCS) & 0xffffff0f) == |
| 191 | ddb_calc_pdar(DDB_INTCS_BASE, DDB_INTCS_SIZE, 8, 0, 0)); |
| 192 | |
| 193 | /* verify BOOT ROM addr */ |
| 194 | /* don't care about some details */ |
| 195 | db_assert((ddb_in32(DDB_BOOTCS) & 0xffffff0f) == |
| 196 | ddb_calc_pdar(DDB_BOOTCS_BASE, DDB_BOOTCS_SIZE, 8, 0, 0)); |
| 197 | |
| 198 | /* setup PCI windows - window1 for MEM/config, window0 for IO */ |
| 199 | ddb_set_pdar(DDB_PCIW0, DDB_PCI_IO_BASE, DDB_PCI_IO_SIZE, 32, 0, 1); |
| 200 | ddb_set_pmr(DDB_PCIINIT0, DDB_PCICMD_IO, 0, DDB_PCI_ACCESS_32); |
| 201 | |
| 202 | ddb_set_pdar(DDB_PCIW1, DDB_PCI_MEM_BASE, DDB_PCI_MEM_SIZE, 32, 0, 1); |
| 203 | ddb_set_pmr(DDB_PCIINIT1, DDB_PCICMD_MEM, DDB_PCI_MEM_BASE, DDB_PCI_ACCESS_32); |
| 204 | |
| 205 | /* ----------- setup PDARs ------------ */ |
| 206 | /* this is problematic - it will reset Aladin which cause we loose |
| 207 | * serial port, and we don't know how to set up Aladin chip again. |
| 208 | */ |
| 209 | // ddb_pci_reset_bus(); |
| 210 | |
| 211 | ddb_out32(DDB_BAR0, 0x00000008); |
| 212 | |
| 213 | ddb_out32(DDB_BARC, 0xffffffff); |
| 214 | ddb_out32(DDB_BARB, 0xffffffff); |
| 215 | ddb_out32(DDB_BAR1, 0xffffffff); |
| 216 | ddb_out32(DDB_BAR2, 0xffffffff); |
| 217 | ddb_out32(DDB_BAR3, 0xffffffff); |
| 218 | ddb_out32(DDB_BAR4, 0xffffffff); |
| 219 | ddb_out32(DDB_BAR5, 0xffffffff); |
| 220 | ddb_out32(DDB_BAR6, 0xffffffff); |
| 221 | ddb_out32(DDB_BAR7, 0xffffffff); |
| 222 | ddb_out32(DDB_BAR8, 0xffffffff); |
| 223 | |
| 224 | /* ----------- switch PCI1 to PCI CONFIG space ------------ */ |
| 225 | ddb_set_pdar(DDB_PCIW1, DDB_PCI_CONFIG_BASE, DDB_PCI_CONFIG_SIZE, 32, 0, 1); |
| 226 | ddb_set_pmr(DDB_PCIINIT1, DDB_PCICMD_CFG, 0x0, DDB_PCI_ACCESS_32); |
| 227 | |
| 228 | /* ----- M1543 PCI setup ------ */ |
| 229 | |
| 230 | /* we know M1543 PCI-ISA controller is at addr:18 */ |
| 231 | /* xxxx1010 makes USB at addr:13 and PMU at addr:14 */ |
| 232 | *(volatile unsigned char *) 0xa8040072 &= 0xf0; |
| 233 | *(volatile unsigned char *) 0xa8040072 |= 0xa; |
| 234 | |
| 235 | /* setup USB interrupt to IRQ 9, (bit 0:3 - 0001) |
| 236 | * no IOCHRDY signal, (bit 7 - 1) |
| 237 | * M1543C & M7101 VID and Subsys Device ID are read-only (bit 6 - 1) |
| 238 | * Make USB Master INTAJ level to edge conversion (bit 4 - 1) |
| 239 | */ |
| 240 | *(unsigned char *) 0xa8040074 = 0xd1; |
| 241 | |
| 242 | /* setup PMU(SCI to IRQ 10 (bit 0:3 - 0011) |
| 243 | * SCI routing to IRQ 13 disabled (bit 7 - 1) |
| 244 | * SCI interrupt level to edge conversion bypassed (bit 4 - 0) |
| 245 | */ |
| 246 | *(unsigned char *) 0xa8040076 = 0x83; |
| 247 | |
| 248 | /* setup IDE controller |
| 249 | * enable IDE controller (bit 6 - 1) |
| 250 | * IDE IDSEL to be addr:24 (bit 4:5 - 11) |
| 251 | * no IDE ATA Secondary Bus Signal Pad Control (bit 3 - 0) |
| 252 | * no IDE ATA Primary Bus Signal Pad Control (bit 2 - 0) |
| 253 | * primary IRQ is 14, secondary is 15 (bit 1:0 - 01 |
| 254 | */ |
| 255 | // *(unsigned char*)0xa8040058 = 0x71; |
| 256 | // *(unsigned char*)0xa8040058 = 0x79; |
| 257 | // *(unsigned char*)0xa8040058 = 0x74; // use SIRQ, primary tri-state |
| 258 | *(unsigned char *) 0xa8040058 = 0x75; // primary tri-state |
| 259 | |
| 260 | #if 0 |
| 261 | /* this is not necessary if M5229 does not use SIRQ */ |
| 262 | *(unsigned char *) 0xa8040044 = 0x0d; // primary to IRQ 14 |
| 263 | *(unsigned char *) 0xa8040075 = 0x0d; // secondary to IRQ 14 |
| 264 | #endif |
| 265 | |
| 266 | /* enable IDE in the M5229 config register 0x50 (bit 0 - 1) */ |
| 267 | /* M5229 IDSEL is addr:24; see above setting */ |
| 268 | *(unsigned char *) 0xa9000050 |= 0x1; |
| 269 | |
| 270 | /* enable bus master (bit 2) and IO decoding (bit 0) */ |
| 271 | *(unsigned char *) 0xa9000004 |= 0x5; |
| 272 | |
| 273 | /* enable native, copied from arch/ppc/k2boot/head.S */ |
| 274 | /* TODO - need volatile, need to be portable */ |
| 275 | *(unsigned char *) 0xa9000009 = 0xff; |
| 276 | |
| 277 | /* ----- end of M1543 PCI setup ------ */ |
| 278 | |
| 279 | /* ----- reset on-board ether chip ------ */ |
| 280 | *((volatile u32 *) 0xa8020004) |= 1; /* decode I/O */ |
| 281 | *((volatile u32 *) 0xa8020010) = 0; /* set BAR address */ |
| 282 | |
| 283 | /* send reset command */ |
| 284 | *((volatile u32 *) 0xa6000000) = 1; /* do a soft reset */ |
| 285 | |
| 286 | /* disable ether chip */ |
| 287 | *((volatile u32 *) 0xa8020004) = 0; /* disable any decoding */ |
| 288 | |
| 289 | /* put it into sleep */ |
| 290 | *((volatile u32 *) 0xa8020040) = 0x80000000; |
| 291 | |
| 292 | /* ----- end of reset on-board ether chip ------ */ |
| 293 | |
| 294 | /* ----------- switch PCI1 back to PCI MEM space ------------ */ |
| 295 | ddb_set_pdar(DDB_PCIW1, DDB_PCI_MEM_BASE, DDB_PCI_MEM_SIZE, 32, 0, 1); |
| 296 | ddb_set_pmr(DDB_PCIINIT1, DDB_PCICMD_MEM, DDB_PCI_MEM_BASE, DDB_PCI_ACCESS_32); |
| 297 | } |