aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ppc/platforms
diff options
context:
space:
mode:
authorRoland Dreier <rolandd@cisco.com>2005-11-07 03:58:14 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2005-11-07 10:53:26 -0500
commit90eb2665841d7b444602736e2141a01c948f75b1 (patch)
tree91300cf853d68a68dcefd62d7bdee28b5a441162 /arch/ppc/platforms
parentb0f7b8bc57ee90138a7c429951457027a90c326f (diff)
[PATCH] ppc32: Add Yucca (440SPe eval board) platform
Add support for AMCC PowerPC 440SPe "Yucca" eval board platform. Signed-off-by: Roland Dreier <rolandd@cisco.com> Cc: Matt Porter <mporter@kernel.crashing.org> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/ppc/platforms')
-rw-r--r--arch/ppc/platforms/4xx/Kconfig11
-rw-r--r--arch/ppc/platforms/4xx/Makefile1
-rw-r--r--arch/ppc/platforms/4xx/yucca.c395
-rw-r--r--arch/ppc/platforms/4xx/yucca.h111
4 files changed, 516 insertions, 2 deletions
diff --git a/arch/ppc/platforms/4xx/Kconfig b/arch/ppc/platforms/4xx/Kconfig
index 108d5a730f84..e70e4c6ec787 100644
--- a/arch/ppc/platforms/4xx/Kconfig
+++ b/arch/ppc/platforms/4xx/Kconfig
@@ -82,6 +82,12 @@ config LUAN
82 help 82 help
83 This option enables support for the IBM PPC440SP evaluation board. 83 This option enables support for the IBM PPC440SP evaluation board.
84 84
85config YUCCA
86 bool "Yucca"
87 select WANT_EARLY_SERIAL
88 help
89 This option enables support for the AMCC PPC440SPe evaluation board.
90
85config OCOTEA 91config OCOTEA
86 bool "Ocotea" 92 bool "Ocotea"
87 select WANT_EARLY_SERIAL 93 select WANT_EARLY_SERIAL
@@ -126,7 +132,8 @@ config 440SP
126 132
127config 440SPE 133config 440SPE
128 bool 134 bool
129 default n 135 depends on YUCCA
136 default y
130 137
131config 440 138config 440
132 bool 139 bool
@@ -162,7 +169,7 @@ config BOOKE
162 169
163config IBM_OCP 170config IBM_OCP
164 bool 171 bool
165 depends on ASH || BAMBOO || BUBINGA || CPCI405 || EBONY || EP405 || LUAN || OCOTEA || REDWOOD_5 || REDWOOD_6 || SYCAMORE || WALNUT 172 depends on ASH || BAMBOO || BUBINGA || CPCI405 || EBONY || EP405 || LUAN || YUCCA || OCOTEA || REDWOOD_5 || REDWOOD_6 || SYCAMORE || WALNUT
166 default y 173 default y
167 174
168config XILINX_OCP 175config XILINX_OCP
diff --git a/arch/ppc/platforms/4xx/Makefile b/arch/ppc/platforms/4xx/Makefile
index 694accdb59f7..c9bb61170954 100644
--- a/arch/ppc/platforms/4xx/Makefile
+++ b/arch/ppc/platforms/4xx/Makefile
@@ -7,6 +7,7 @@ obj-$(CONFIG_EBONY) += ebony.o
7obj-$(CONFIG_EP405) += ep405.o 7obj-$(CONFIG_EP405) += ep405.o
8obj-$(CONFIG_BUBINGA) += bubinga.o 8obj-$(CONFIG_BUBINGA) += bubinga.o
9obj-$(CONFIG_LUAN) += luan.o 9obj-$(CONFIG_LUAN) += luan.o
10obj-$(CONFIG_YUCCA) += yucca.o
10obj-$(CONFIG_OCOTEA) += ocotea.o 11obj-$(CONFIG_OCOTEA) += ocotea.o
11obj-$(CONFIG_REDWOOD_5) += redwood5.o 12obj-$(CONFIG_REDWOOD_5) += redwood5.o
12obj-$(CONFIG_REDWOOD_6) += redwood6.o 13obj-$(CONFIG_REDWOOD_6) += redwood6.o
diff --git a/arch/ppc/platforms/4xx/yucca.c b/arch/ppc/platforms/4xx/yucca.c
new file mode 100644
index 000000000000..e60f4bd437ec
--- /dev/null
+++ b/arch/ppc/platforms/4xx/yucca.c
@@ -0,0 +1,395 @@
1/*
2 * arch/ppc/platforms/4xx/yucca.c
3 *
4 * Yucca board specific routines
5 *
6 * Roland Dreier <rolandd@cisco.com> (based on luan.c by Matt Porter)
7 *
8 * Copyright 2004-2005 MontaVista Software Inc.
9 * Copyright (c) 2005 Cisco Systems. All rights reserved.
10 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the
13 * Free Software Foundation; either version 2 of the License, or (at your
14 * option) any later version.
15 */
16
17#include <linux/config.h>
18#include <linux/stddef.h>
19#include <linux/kernel.h>
20#include <linux/init.h>
21#include <linux/errno.h>
22#include <linux/reboot.h>
23#include <linux/pci.h>
24#include <linux/kdev_t.h>
25#include <linux/types.h>
26#include <linux/major.h>
27#include <linux/blkdev.h>
28#include <linux/console.h>
29#include <linux/delay.h>
30#include <linux/ide.h>
31#include <linux/initrd.h>
32#include <linux/seq_file.h>
33#include <linux/root_dev.h>
34#include <linux/tty.h>
35#include <linux/serial.h>
36#include <linux/serial_core.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/ibm44x_common.h>
53#include <syslib/ibm440gx_common.h>
54#include <syslib/ibm440sp_common.h>
55#include <syslib/ppc440spe_pcie.h>
56
57extern bd_t __res;
58
59static struct ibm44x_clocks clocks __initdata;
60
61static void __init
62yucca_calibrate_decr(void)
63{
64 unsigned int freq;
65
66 if (mfspr(SPRN_CCR1) & CCR1_TCS)
67 freq = YUCCA_TMR_CLK;
68 else
69 freq = clocks.cpu;
70
71 ibm44x_calibrate_decr(freq);
72}
73
74static int
75yucca_show_cpuinfo(struct seq_file *m)
76{
77 seq_printf(m, "vendor\t\t: AMCC\n");
78 seq_printf(m, "machine\t\t: PPC440SPe EVB (Yucca)\n");
79
80 return 0;
81}
82
83static enum {
84 HOSE_UNKNOWN,
85 HOSE_PCIX,
86 HOSE_PCIE0,
87 HOSE_PCIE1,
88 HOSE_PCIE2
89} hose_type[4];
90
91static inline int
92yucca_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
93{
94 struct pci_controller *hose = pci_bus_to_hose(dev->bus->number);
95
96 if (hose_type[hose->index] == HOSE_PCIX) {
97 static char pci_irq_table[][4] =
98 /*
99 * PCI IDSEL/INTPIN->INTLINE
100 * A B C D
101 */
102 {
103 { 81, -1, -1, -1 }, /* IDSEL 1 - PCIX0 Slot 0 */
104 };
105 const long min_idsel = 1, max_idsel = 1, irqs_per_slot = 4;
106 return PCI_IRQ_TABLE_LOOKUP;
107 } else if (hose_type[hose->index] == HOSE_PCIE0) {
108 static char pci_irq_table[][4] =
109 /*
110 * PCI IDSEL/INTPIN->INTLINE
111 * A B C D
112 */
113 {
114 { 96, 97, 98, 99 },
115 };
116 const long min_idsel = 1, max_idsel = 1, irqs_per_slot = 4;
117 return PCI_IRQ_TABLE_LOOKUP;
118 } else if (hose_type[hose->index] == HOSE_PCIE1) {
119 static char pci_irq_table[][4] =
120 /*
121 * PCI IDSEL/INTPIN->INTLINE
122 * A B C D
123 */
124 {
125 { 100, 101, 102, 103 },
126 };
127 const long min_idsel = 1, max_idsel = 1, irqs_per_slot = 4;
128 return PCI_IRQ_TABLE_LOOKUP;
129 } else if (hose_type[hose->index] == HOSE_PCIE2) {
130 static char pci_irq_table[][4] =
131 /*
132 * PCI IDSEL/INTPIN->INTLINE
133 * A B C D
134 */
135 {
136 { 104, 105, 106, 107 },
137 };
138 const long min_idsel = 1, max_idsel = 1, irqs_per_slot = 4;
139 return PCI_IRQ_TABLE_LOOKUP;
140 }
141 return -1;
142}
143
144static void __init yucca_set_emacdata(void)
145{
146 struct ocp_def *def;
147 struct ocp_func_emac_data *emacdata;
148
149 /* Set phy_map, phy_mode, and mac_addr for the EMAC */
150 def = ocp_get_one_device(OCP_VENDOR_IBM, OCP_FUNC_EMAC, 0);
151 emacdata = def->additions;
152 emacdata->phy_map = 0x00000001; /* Skip 0x00 */
153 emacdata->phy_mode = PHY_MODE_GMII;
154 memcpy(emacdata->mac_addr, __res.bi_enetaddr, 6);
155}
156
157static int __init yucca_pcie_card_present(int port)
158{
159 void __iomem *pcie_fpga_base;
160 u16 reg;
161
162 pcie_fpga_base = ioremap64(YUCCA_FPGA_REG_BASE, YUCCA_FPGA_REG_SIZE);
163 reg = in_be16(pcie_fpga_base + FPGA_REG1C);
164 iounmap(pcie_fpga_base);
165
166 switch(port) {
167 case 0: return !(reg & FPGA_REG1C_PE0_PRSNT);
168 case 1: return !(reg & FPGA_REG1C_PE1_PRSNT);
169 case 2: return !(reg & FPGA_REG1C_PE2_PRSNT);
170 default: return 0;
171 }
172}
173
174/*
175 * For the given slot, set rootpoint mode, send power to the slot,
176 * turn on the green LED and turn off the yellow LED, enable the clock
177 * and turn off reset.
178 */
179static void __init yucca_setup_pcie_fpga_rootpoint(int port)
180{
181 void __iomem *pcie_reg_fpga_base;
182 u16 power, clock, green_led, yellow_led, reset_off, rootpoint, endpoint;
183
184 pcie_reg_fpga_base = ioremap64(YUCCA_FPGA_REG_BASE, YUCCA_FPGA_REG_SIZE);
185
186 switch(port) {
187 case 0:
188 rootpoint = FPGA_REG1C_PE0_ROOTPOINT;
189 endpoint = 0;
190 power = FPGA_REG1A_PE0_PWRON;
191 green_led = FPGA_REG1A_PE0_GLED;
192 clock = FPGA_REG1A_PE0_REFCLK_ENABLE;
193 yellow_led = FPGA_REG1A_PE0_YLED;
194 reset_off = FPGA_REG1C_PE0_PERST;
195 break;
196 case 1:
197 rootpoint = 0;
198 endpoint = FPGA_REG1C_PE1_ENDPOINT;
199 power = FPGA_REG1A_PE1_PWRON;
200 green_led = FPGA_REG1A_PE1_GLED;
201 clock = FPGA_REG1A_PE1_REFCLK_ENABLE;
202 yellow_led = FPGA_REG1A_PE1_YLED;
203 reset_off = FPGA_REG1C_PE1_PERST;
204 break;
205 case 2:
206 rootpoint = 0;
207 endpoint = FPGA_REG1C_PE2_ENDPOINT;
208 power = FPGA_REG1A_PE2_PWRON;
209 green_led = FPGA_REG1A_PE2_GLED;
210 clock = FPGA_REG1A_PE2_REFCLK_ENABLE;
211 yellow_led = FPGA_REG1A_PE2_YLED;
212 reset_off = FPGA_REG1C_PE2_PERST;
213 break;
214
215 default:
216 return;
217 }
218
219 out_be16(pcie_reg_fpga_base + FPGA_REG1A,
220 ~(power | clock | green_led) &
221 (yellow_led | in_be16(pcie_reg_fpga_base + FPGA_REG1A)));
222 out_be16(pcie_reg_fpga_base + FPGA_REG1C,
223 ~(endpoint | reset_off) &
224 (rootpoint | in_be16(pcie_reg_fpga_base + FPGA_REG1C)));
225
226 /*
227 * Leave device in reset for a while after powering on the
228 * slot to give it a chance to initialize.
229 */
230 mdelay(250);
231
232 out_be16(pcie_reg_fpga_base + FPGA_REG1C,
233 reset_off | in_be16(pcie_reg_fpga_base + FPGA_REG1C));
234
235 iounmap(pcie_reg_fpga_base);
236}
237
238static void __init
239yucca_setup_hoses(void)
240{
241 struct pci_controller *hose;
242 char name[20];
243 int i;
244
245 if (0 && ppc440spe_init_pcie()) {
246 printk(KERN_WARNING "PPC440SPe PCI Express initialization failed\n");
247 return;
248 }
249
250 for (i = 0; i <= 2; ++i) {
251 if (!yucca_pcie_card_present(i))
252 continue;
253
254 printk(KERN_INFO "PCIE%d: card present\n", i);
255 yucca_setup_pcie_fpga_rootpoint(i);
256 if (ppc440spe_init_pcie_rootport(i)) {
257 printk(KERN_WARNING "PCIE%d: initialization failed\n", i);
258 continue;
259 }
260
261 hose = pcibios_alloc_controller();
262 if (!hose)
263 return;
264
265 sprintf(name, "PCIE%d host bridge", i);
266 pci_init_resource(&hose->io_resource,
267 YUCCA_PCIX_LOWER_IO,
268 YUCCA_PCIX_UPPER_IO,
269 IORESOURCE_IO,
270 name);
271
272 hose->mem_space.start = YUCCA_PCIE_LOWER_MEM +
273 i * YUCCA_PCIE_MEM_SIZE;
274 hose->mem_space.end = hose->mem_space.start +
275 YUCCA_PCIE_MEM_SIZE - 1;
276
277 pci_init_resource(&hose->mem_resources[0],
278 hose->mem_space.start,
279 hose->mem_space.end,
280 IORESOURCE_MEM,
281 name);
282
283 hose->first_busno = 0;
284 hose->last_busno = 15;
285 hose_type[hose->index] = HOSE_PCIE0 + i;
286
287 ppc440spe_setup_pcie(hose, i);
288 hose->last_busno = pciauto_bus_scan(hose, hose->first_busno);
289 }
290
291 ppc_md.pci_swizzle = common_swizzle;
292 ppc_md.pci_map_irq = yucca_map_irq;
293}
294
295TODC_ALLOC();
296
297static void __init
298yucca_early_serial_map(void)
299{
300 struct uart_port port;
301
302 /* Setup ioremapped serial port access */
303 memset(&port, 0, sizeof(port));
304 port.membase = ioremap64(PPC440SPE_UART0_ADDR, 8);
305 port.irq = UART0_INT;
306 port.uartclk = clocks.uart0;
307 port.regshift = 0;
308 port.iotype = SERIAL_IO_MEM;
309 port.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST;
310 port.line = 0;
311
312 if (early_serial_setup(&port) != 0) {
313 printk("Early serial init of port 0 failed\n");
314 }
315
316 port.membase = ioremap64(PPC440SPE_UART1_ADDR, 8);
317 port.irq = UART1_INT;
318 port.uartclk = clocks.uart1;
319 port.line = 1;
320
321 if (early_serial_setup(&port) != 0) {
322 printk("Early serial init of port 1 failed\n");
323 }
324
325 port.membase = ioremap64(PPC440SPE_UART2_ADDR, 8);
326 port.irq = UART2_INT;
327 port.uartclk = BASE_BAUD;
328 port.line = 2;
329
330 if (early_serial_setup(&port) != 0) {
331 printk("Early serial init of port 2 failed\n");
332 }
333}
334
335static void __init
336yucca_setup_arch(void)
337{
338 yucca_set_emacdata();
339
340#if !defined(CONFIG_BDI_SWITCH)
341 /*
342 * The Abatron BDI JTAG debugger does not tolerate others
343 * mucking with the debug registers.
344 */
345 mtspr(SPRN_DBCR0, (DBCR0_TDE | DBCR0_IDM));
346#endif
347
348 /*
349 * Determine various clocks.
350 * To be completely correct we should get SysClk
351 * from FPGA, because it can be changed by on-board switches
352 * --ebs
353 */
354 /* 440GX and 440SPe clocking is the same - rd */
355 ibm440gx_get_clocks(&clocks, 33333333, 6 * 1843200);
356 ocp_sys_info.opb_bus_freq = clocks.opb;
357
358 /* init to some ~sane value until calibrate_delay() runs */
359 loops_per_jiffy = 50000000/HZ;
360
361 /* Setup PCIXn host bridges */
362 yucca_setup_hoses();
363
364#ifdef CONFIG_BLK_DEV_INITRD
365 if (initrd_start)
366 ROOT_DEV = Root_RAM0;
367 else
368#endif
369#ifdef CONFIG_ROOT_NFS
370 ROOT_DEV = Root_NFS;
371#else
372 ROOT_DEV = Root_HDA1;
373#endif
374
375 yucca_early_serial_map();
376
377 /* Identify the system */
378 printk("Yucca port (Roland Dreier <rolandd@cisco.com>)\n");
379}
380
381void __init platform_init(unsigned long r3, unsigned long r4,
382 unsigned long r5, unsigned long r6, unsigned long r7)
383{
384 ibm44x_platform_init(r3, r4, r5, r6, r7);
385
386 ppc_md.setup_arch = yucca_setup_arch;
387 ppc_md.show_cpuinfo = yucca_show_cpuinfo;
388 ppc_md.find_end_of_memory = ibm440sp_find_end_of_memory;
389 ppc_md.get_irq = NULL; /* Set in ppc4xx_pic_init() */
390
391 ppc_md.calibrate_decr = yucca_calibrate_decr;
392#ifdef CONFIG_KGDB
393 ppc_md.early_serial_map = yucca_early_serial_map;
394#endif
395}
diff --git a/arch/ppc/platforms/4xx/yucca.h b/arch/ppc/platforms/4xx/yucca.h
new file mode 100644
index 000000000000..01a4afea1514
--- /dev/null
+++ b/arch/ppc/platforms/4xx/yucca.h
@@ -0,0 +1,111 @@
1/*
2 * arch/ppc/platforms/4xx/yucca.h
3 *
4 * Yucca board definitions
5 *
6 * Roland Dreier <rolandd@cisco.com> (based on luan.h by Matt Porter)
7 *
8 * Copyright 2004-2005 MontaVista Software Inc.
9 * Copyright (c) 2005 Cisco Systems. All rights reserved.
10 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the
13 * Free Software Foundation; either version 2 of the License, or (at your
14 * option) any later version.
15 *
16 */
17
18#ifdef __KERNEL__
19#ifndef __ASM_YUCCA_H__
20#define __ASM_YUCCA_H__
21
22#include <linux/config.h>
23#include <platforms/4xx/ppc440spe.h>
24
25/* F/W TLB mapping used in bootloader glue to reset EMAC */
26#define PPC44x_EMAC0_MR0 0xa0000800
27
28/* Location of MAC addresses in PIBS image */
29#define PIBS_FLASH_BASE 0xffe00000
30#define PIBS_MAC_BASE (PIBS_FLASH_BASE+0x1b0400)
31
32/* External timer clock frequency */
33#define YUCCA_TMR_CLK 25000000
34
35/*
36 * FPGA registers
37 */
38#define YUCCA_FPGA_REG_BASE 0x00000004e2000000ULL
39#define YUCCA_FPGA_REG_SIZE 0x24
40
41#define FPGA_REG1A 0x1a
42
43#define FPGA_REG1A_PE0_GLED 0x8000
44#define FPGA_REG1A_PE1_GLED 0x4000
45#define FPGA_REG1A_PE2_GLED 0x2000
46#define FPGA_REG1A_PE0_YLED 0x1000
47#define FPGA_REG1A_PE1_YLED 0x0800
48#define FPGA_REG1A_PE2_YLED 0x0400
49#define FPGA_REG1A_PE0_PWRON 0x0200
50#define FPGA_REG1A_PE1_PWRON 0x0100
51#define FPGA_REG1A_PE2_PWRON 0x0080
52#define FPGA_REG1A_PE0_REFCLK_ENABLE 0x0040
53#define FPGA_REG1A_PE1_REFCLK_ENABLE 0x0020
54#define FPGA_REG1A_PE2_REFCLK_ENABLE 0x0010
55#define FPGA_REG1A_PE_SPREAD0 0x0008
56#define FPGA_REG1A_PE_SPREAD1 0x0004
57#define FPGA_REG1A_PE_SELSOURCE_0 0x0002
58#define FPGA_REG1A_PE_SELSOURCE_1 0x0001
59
60#define FPGA_REG1C 0x1c
61
62#define FPGA_REG1C_PE0_ROOTPOINT 0x8000
63#define FPGA_REG1C_PE1_ENDPOINT 0x4000
64#define FPGA_REG1C_PE2_ENDPOINT 0x2000
65#define FPGA_REG1C_PE0_PRSNT 0x1000
66#define FPGA_REG1C_PE1_PRSNT 0x0800
67#define FPGA_REG1C_PE2_PRSNT 0x0400
68#define FPGA_REG1C_PE0_WAKE 0x0080
69#define FPGA_REG1C_PE1_WAKE 0x0040
70#define FPGA_REG1C_PE2_WAKE 0x0020
71#define FPGA_REG1C_PE0_PERST 0x0010
72#define FPGA_REG1C_PE1_PERST 0x0008
73#define FPGA_REG1C_PE2_PERST 0x0004
74
75/*
76 * Serial port defines
77 */
78#define RS_TABLE_SIZE 3
79
80/* PIBS defined UART mappings, used before early_serial_setup */
81#define UART0_IO_BASE 0xa0000200
82#define UART1_IO_BASE 0xa0000300
83#define UART2_IO_BASE 0xa0000600
84
85#define BASE_BAUD 11059200
86#define STD_UART_OP(num) \
87 { 0, BASE_BAUD, 0, UART##num##_INT, \
88 (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST), \
89 iomem_base: (void*)UART##num##_IO_BASE, \
90 io_type: SERIAL_IO_MEM},
91
92#define SERIAL_PORT_DFNS \
93 STD_UART_OP(0) \
94 STD_UART_OP(1) \
95 STD_UART_OP(2)
96
97/* PCI support */
98#define YUCCA_PCIX_LOWER_IO 0x00000000
99#define YUCCA_PCIX_UPPER_IO 0x0000ffff
100#define YUCCA_PCIX_LOWER_MEM 0x80000000
101#define YUCCA_PCIX_UPPER_MEM 0x8fffffff
102#define YUCCA_PCIE_LOWER_MEM 0x90000000
103#define YUCCA_PCIE_MEM_SIZE 0x10000000
104
105#define YUCCA_PCIX_MEM_SIZE 0x10000000
106#define YUCCA_PCIX_MEM_OFFSET 0x00000000
107#define YUCCA_PCIE_MEM_SIZE 0x10000000
108#define YUCCA_PCIE_MEM_OFFSET 0x00000000
109
110#endif /* __ASM_YUCCA_H__ */
111#endif /* __KERNEL__ */