]> pilppa.org Git - linux-2.6-omap-h63xx.git/blob - arch/ppc/platforms/4xx/bamboo.c
Merge master.kernel.org:/pub/scm/linux/kernel/git/chrisw/lsm-2.6
[linux-2.6-omap-h63xx.git] / arch / ppc / platforms / 4xx / bamboo.c
1 /*
2  * arch/ppc/platforms/4xx/bamboo.c
3  *
4  * Bamboo board specific routines
5  *
6  * Wade Farnsworth <wfarnsworth@mvista.com>
7  * Copyright 2004 MontaVista Software Inc.
8  *
9  * This program is free software; you can redistribute  it and/or modify it
10  * under  the terms of  the GNU General  Public License as published by the
11  * Free Software Foundation;  either version 2 of the  License, or (at your
12  * option) any later version.
13  */
14
15 #include <linux/config.h>
16 #include <linux/stddef.h>
17 #include <linux/kernel.h>
18 #include <linux/init.h>
19 #include <linux/errno.h>
20 #include <linux/reboot.h>
21 #include <linux/pci.h>
22 #include <linux/kdev_t.h>
23 #include <linux/types.h>
24 #include <linux/major.h>
25 #include <linux/blkdev.h>
26 #include <linux/console.h>
27 #include <linux/delay.h>
28 #include <linux/ide.h>
29 #include <linux/initrd.h>
30 #include <linux/irq.h>
31 #include <linux/seq_file.h>
32 #include <linux/root_dev.h>
33 #include <linux/tty.h>
34 #include <linux/serial.h>
35 #include <linux/serial_core.h>
36 #include <linux/ethtool.h>
37
38 #include <asm/system.h>
39 #include <asm/pgtable.h>
40 #include <asm/page.h>
41 #include <asm/dma.h>
42 #include <asm/io.h>
43 #include <asm/machdep.h>
44 #include <asm/ocp.h>
45 #include <asm/pci-bridge.h>
46 #include <asm/time.h>
47 #include <asm/todc.h>
48 #include <asm/bootinfo.h>
49 #include <asm/ppc4xx_pic.h>
50 #include <asm/ppcboot.h>
51
52 #include <syslib/gen550.h>
53 #include <syslib/ibm440gx_common.h>
54
55 bd_t __res;
56
57 static struct ibm44x_clocks clocks __initdata;
58
59 /*
60  * Bamboo external IRQ triggering/polarity settings
61  */
62 unsigned char ppc4xx_uic_ext_irq_cfg[] __initdata = {
63         (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ0: Ethernet transceiver */
64         (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* IRQ1: Expansion connector */
65         (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ2: PCI slot 0 */
66         (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ3: PCI slot 1 */
67         (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ4: PCI slot 2 */
68         (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ5: PCI slot 3 */
69         (IRQ_SENSE_EDGE  | IRQ_POLARITY_NEGATIVE), /* IRQ6: SMI pushbutton */
70         (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ7: EXT */
71         (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ8: EXT */
72         (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ9: EXT */
73 };
74
75 static void __init
76 bamboo_calibrate_decr(void)
77 {
78         unsigned int freq;
79
80         if (mfspr(SPRN_CCR1) & CCR1_TCS)
81                 freq = BAMBOO_TMRCLK;
82         else
83                 freq = clocks.cpu;
84
85         ibm44x_calibrate_decr(freq);
86
87 }
88
89 static int
90 bamboo_show_cpuinfo(struct seq_file *m)
91 {
92         seq_printf(m, "vendor\t\t: IBM\n");
93         seq_printf(m, "machine\t\t: PPC440EP EVB (Bamboo)\n");
94
95         return 0;
96 }
97
98 static inline int
99 bamboo_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
100 {
101         static char pci_irq_table[][4] =
102         /*
103          *      PCI IDSEL/INTPIN->INTLINE
104          *         A   B   C   D
105          */
106         {
107                 { 28, 28, 28, 28 },     /* IDSEL 1 - PCI Slot 0 */
108                 { 27, 27, 27, 27 },     /* IDSEL 2 - PCI Slot 1 */
109                 { 26, 26, 26, 26 },     /* IDSEL 3 - PCI Slot 2 */
110                 { 25, 25, 25, 25 },     /* IDSEL 4 - PCI Slot 3 */
111         };
112
113         const long min_idsel = 1, max_idsel = 4, irqs_per_slot = 4;
114         return PCI_IRQ_TABLE_LOOKUP;
115 }
116
117 static void __init bamboo_set_emacdata(void)
118 {
119         u8 * base_addr;
120         struct ocp_def *def;
121         struct ocp_func_emac_data *emacdata;
122         u8 val;
123         int mode;
124         u32 excluded = 0;
125
126         base_addr = ioremap64(BAMBOO_FPGA_SELECTION1_REG_ADDR, 16);
127         val = readb(base_addr);
128         iounmap((void *) base_addr);
129         if (BAMBOO_SEL_MII(val))
130                 mode = PHY_MODE_MII;
131         else if (BAMBOO_SEL_RMII(val))
132                 mode = PHY_MODE_RMII;
133         else
134                 mode = PHY_MODE_SMII;
135
136         /*
137          * SW2 on the Bamboo is used for ethernet configuration and is accessed
138          * via the CONFIG2 register in the FPGA.  If the ANEG pin is set,
139          * overwrite the supported features with the settings in SW2.
140          *
141          * This is used as a workaround for the improperly biased RJ-45 sockets
142          * on the Rev. 0 Bamboo.  By default only 10baseT is functional.
143          * Removing inductors L17 and L18 from the board allows 100baseT, but
144          * disables 10baseT.  The Rev. 1 has no such limitations.
145          */
146
147         base_addr = ioremap64(BAMBOO_FPGA_CONFIG2_REG_ADDR, 8);
148         val = readb(base_addr);
149         iounmap((void *) base_addr);
150         if (!BAMBOO_AUTONEGOTIATE(val)) {
151                 excluded |= SUPPORTED_Autoneg;
152                 if (BAMBOO_FORCE_100Mbps(val)) {
153                         excluded |= SUPPORTED_10baseT_Full;
154                         excluded |= SUPPORTED_10baseT_Half;
155                         if (BAMBOO_FULL_DUPLEX_EN(val))
156                                 excluded |= SUPPORTED_100baseT_Half;
157                         else
158                                 excluded |= SUPPORTED_100baseT_Full;
159                 } else {
160                         excluded |= SUPPORTED_100baseT_Full;
161                         excluded |= SUPPORTED_100baseT_Half;
162                         if (BAMBOO_FULL_DUPLEX_EN(val))
163                                 excluded |= SUPPORTED_10baseT_Half;
164                         else
165                                 excluded |= SUPPORTED_10baseT_Full;
166                 }
167         }
168
169         /* Set mac_addr, phy mode and unsupported phy features for each EMAC */
170
171         def = ocp_get_one_device(OCP_VENDOR_IBM, OCP_FUNC_EMAC, 0);
172         emacdata = def->additions;
173         memcpy(emacdata->mac_addr, __res.bi_enetaddr, 6);
174         emacdata->phy_mode = mode;
175         emacdata->phy_feat_exc = excluded;
176
177         def = ocp_get_one_device(OCP_VENDOR_IBM, OCP_FUNC_EMAC, 1);
178         emacdata = def->additions;
179         memcpy(emacdata->mac_addr, __res.bi_enet1addr, 6);
180         emacdata->phy_mode = mode;
181         emacdata->phy_feat_exc = excluded;
182 }
183
184 static int
185 bamboo_exclude_device(unsigned char bus, unsigned char devfn)
186 {
187         return (bus == 0 && devfn == 0);
188 }
189
190 #define PCI_READW(offset) \
191         (readw((void *)((u32)pci_reg_base+offset)))
192
193 #define PCI_WRITEW(value, offset) \
194         (writew(value, (void *)((u32)pci_reg_base+offset)))
195
196 #define PCI_WRITEL(value, offset) \
197         (writel(value, (void *)((u32)pci_reg_base+offset)))
198
199 static void __init
200 bamboo_setup_pci(void)
201 {
202         void *pci_reg_base;
203         unsigned long memory_size;
204         memory_size = ppc_md.find_end_of_memory();
205
206         pci_reg_base = ioremap64(BAMBOO_PCIL0_BASE, BAMBOO_PCIL0_SIZE);
207
208         /* Enable PCI I/O, Mem, and Busmaster cycles */
209         PCI_WRITEW(PCI_READW(PCI_COMMAND) |
210                    PCI_COMMAND_MEMORY |
211                    PCI_COMMAND_MASTER, PCI_COMMAND);
212
213         /* Disable region first */
214         PCI_WRITEL(0, BAMBOO_PCIL0_PMM0MA);
215
216         /* PLB starting addr: 0x00000000A0000000 */
217         PCI_WRITEL(BAMBOO_PCI_PHY_MEM_BASE, BAMBOO_PCIL0_PMM0LA);
218
219         /* PCI start addr, 0xA0000000 (PCI Address) */
220         PCI_WRITEL(BAMBOO_PCI_MEM_BASE, BAMBOO_PCIL0_PMM0PCILA);
221         PCI_WRITEL(0, BAMBOO_PCIL0_PMM0PCIHA);
222
223         /* Enable no pre-fetch, enable region */
224         PCI_WRITEL(((0xffffffff -
225                      (BAMBOO_PCI_UPPER_MEM - BAMBOO_PCI_MEM_BASE)) | 0x01),
226                       BAMBOO_PCIL0_PMM0MA);
227
228         /* Disable region one */
229         PCI_WRITEL(0, BAMBOO_PCIL0_PMM1MA);
230         PCI_WRITEL(0, BAMBOO_PCIL0_PMM1LA);
231         PCI_WRITEL(0, BAMBOO_PCIL0_PMM1PCILA);
232         PCI_WRITEL(0, BAMBOO_PCIL0_PMM1PCIHA);
233         PCI_WRITEL(0, BAMBOO_PCIL0_PMM1MA);
234
235         /* Disable region two */
236         PCI_WRITEL(0, BAMBOO_PCIL0_PMM2MA);
237         PCI_WRITEL(0, BAMBOO_PCIL0_PMM2LA);
238         PCI_WRITEL(0, BAMBOO_PCIL0_PMM2PCILA);
239         PCI_WRITEL(0, BAMBOO_PCIL0_PMM2PCIHA);
240         PCI_WRITEL(0, BAMBOO_PCIL0_PMM2MA);
241
242         /* Now configure the PCI->PLB windows, we only use PTM1
243          *
244          * For Inbound flow, set the window size to all available memory
245          * This is required because if size is smaller,
246          * then Eth/PCI DD would fail as PCI card not able to access
247          * the memory allocated by DD.
248          */
249
250         PCI_WRITEL(0, BAMBOO_PCIL0_PTM1MS);     /* disabled region 1 */
251         PCI_WRITEL(0, BAMBOO_PCIL0_PTM1LA);     /* begin of address map */
252
253         memory_size = 1 << fls(memory_size - 1);
254
255         /* Size low + Enabled */
256         PCI_WRITEL((0xffffffff - (memory_size - 1)) | 0x1, BAMBOO_PCIL0_PTM1MS);
257
258         eieio();
259         iounmap(pci_reg_base);
260 }
261
262 static void __init
263 bamboo_setup_hose(void)
264 {
265         unsigned int bar_response, bar;
266         struct pci_controller *hose;
267
268         bamboo_setup_pci();
269
270         hose = pcibios_alloc_controller();
271
272         if (!hose)
273                 return;
274
275         hose->first_busno = 0;
276         hose->last_busno = 0xff;
277
278         hose->pci_mem_offset = BAMBOO_PCI_MEM_OFFSET;
279
280         pci_init_resource(&hose->io_resource,
281                         BAMBOO_PCI_LOWER_IO,
282                         BAMBOO_PCI_UPPER_IO,
283                         IORESOURCE_IO,
284                         "PCI host bridge");
285
286         pci_init_resource(&hose->mem_resources[0],
287                         BAMBOO_PCI_LOWER_MEM,
288                         BAMBOO_PCI_UPPER_MEM,
289                         IORESOURCE_MEM,
290                         "PCI host bridge");
291
292         ppc_md.pci_exclude_device = bamboo_exclude_device;
293
294         hose->io_space.start = BAMBOO_PCI_LOWER_IO;
295         hose->io_space.end = BAMBOO_PCI_UPPER_IO;
296         hose->mem_space.start = BAMBOO_PCI_LOWER_MEM;
297         hose->mem_space.end = BAMBOO_PCI_UPPER_MEM;
298         isa_io_base =
299                 (unsigned long)ioremap64(BAMBOO_PCI_IO_BASE, BAMBOO_PCI_IO_SIZE);
300         hose->io_base_virt = (void *)isa_io_base;
301
302         setup_indirect_pci(hose,
303                         BAMBOO_PCI_CFGA_PLB32,
304                         BAMBOO_PCI_CFGD_PLB32);
305         hose->set_cfg_type = 1;
306
307         /* Zero config bars */
308         for (bar = PCI_BASE_ADDRESS_1; bar <= PCI_BASE_ADDRESS_2; bar += 4) {
309                 early_write_config_dword(hose, hose->first_busno,
310                                          PCI_FUNC(hose->first_busno), bar,
311                                          0x00000000);
312                 early_read_config_dword(hose, hose->first_busno,
313                                         PCI_FUNC(hose->first_busno), bar,
314                                         &bar_response);
315         }
316
317         hose->last_busno = pciauto_bus_scan(hose, hose->first_busno);
318
319         ppc_md.pci_swizzle = common_swizzle;
320         ppc_md.pci_map_irq = bamboo_map_irq;
321 }
322
323 TODC_ALLOC();
324
325 static void __init
326 bamboo_early_serial_map(void)
327 {
328         struct uart_port port;
329
330         /* Setup ioremapped serial port access */
331         memset(&port, 0, sizeof(port));
332         port.membase = ioremap64(PPC440EP_UART0_ADDR, 8);
333         port.irq = 0;
334         port.uartclk = clocks.uart0;
335         port.regshift = 0;
336         port.iotype = SERIAL_IO_MEM;
337         port.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST;
338         port.line = 0;
339
340         if (early_serial_setup(&port) != 0) {
341                 printk("Early serial init of port 0 failed\n");
342         }
343
344 #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB)
345         /* Configure debug serial access */
346         gen550_init(0, &port);
347 #endif
348
349         port.membase = ioremap64(PPC440EP_UART1_ADDR, 8);
350         port.irq = 1;
351         port.uartclk = clocks.uart1;
352         port.line = 1;
353
354         if (early_serial_setup(&port) != 0) {
355                 printk("Early serial init of port 1 failed\n");
356         }
357
358 #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB)
359         /* Configure debug serial access */
360         gen550_init(1, &port);
361 #endif
362
363         port.membase = ioremap64(PPC440EP_UART2_ADDR, 8);
364         port.irq = 3;
365         port.uartclk = clocks.uart2;
366         port.line = 2;
367
368         if (early_serial_setup(&port) != 0) {
369                 printk("Early serial init of port 2 failed\n");
370         }
371
372 #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB)
373         /* Configure debug serial access */
374         gen550_init(2, &port);
375 #endif
376
377         port.membase = ioremap64(PPC440EP_UART3_ADDR, 8);
378         port.irq = 4;
379         port.uartclk = clocks.uart3;
380         port.line = 3;
381
382         if (early_serial_setup(&port) != 0) {
383                 printk("Early serial init of port 3 failed\n");
384         }
385 }
386
387 static void __init
388 bamboo_setup_arch(void)
389 {
390
391         bamboo_set_emacdata();
392
393         ibm440gx_get_clocks(&clocks, 33333333, 6 * 1843200);
394         ocp_sys_info.opb_bus_freq = clocks.opb;
395
396         /* Setup TODC access */
397         TODC_INIT(TODC_TYPE_DS1743,
398                         0,
399                         0,
400                         ioremap64(BAMBOO_RTC_ADDR, BAMBOO_RTC_SIZE),
401                         8);
402
403         /* init to some ~sane value until calibrate_delay() runs */
404         loops_per_jiffy = 50000000/HZ;
405
406         /* Setup PCI host bridge */
407         bamboo_setup_hose();
408
409 #ifdef CONFIG_BLK_DEV_INITRD
410         if (initrd_start)
411                 ROOT_DEV = Root_RAM0;
412         else
413 #endif
414 #ifdef CONFIG_ROOT_NFS
415                 ROOT_DEV = Root_NFS;
416 #else
417                 ROOT_DEV = Root_HDA1;
418 #endif
419
420         bamboo_early_serial_map();
421
422         /* Identify the system */
423         printk("IBM Bamboo port (MontaVista Software, Inc. (source@mvista.com))\n");
424 }
425
426 void __init platform_init(unsigned long r3, unsigned long r4,
427                 unsigned long r5, unsigned long r6, unsigned long r7)
428 {
429         parse_bootinfo(find_bootinfo());
430
431         /*
432          * If we were passed in a board information, copy it into the
433          * residual data area.
434          */
435         if (r3)
436                 __res = *(bd_t *)(r3 + KERNELBASE);
437
438
439         ibm44x_platform_init();
440
441         ppc_md.setup_arch = bamboo_setup_arch;
442         ppc_md.show_cpuinfo = bamboo_show_cpuinfo;
443         ppc_md.get_irq = NULL;          /* Set in ppc4xx_pic_init() */
444
445         ppc_md.calibrate_decr = bamboo_calibrate_decr;
446         ppc_md.time_init = todc_time_init;
447         ppc_md.set_rtc_time = todc_set_rtc_time;
448         ppc_md.get_rtc_time = todc_get_rtc_time;
449
450         ppc_md.nvram_read_val = todc_direct_read_val;
451         ppc_md.nvram_write_val = todc_direct_write_val;
452 #ifdef CONFIG_KGDB
453         ppc_md.early_serial_map = bamboo_early_serial_map;
454 #endif
455 }
456