aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ppc/platforms
diff options
context:
space:
mode:
authorKumar Gala <galak@gate.crashing.org>2005-12-09 12:57:44 -0500
committerPaul Mackerras <paulus@samba.org>2006-01-08 22:53:08 -0500
commita819f8ba76e81669fcc2665ac532cac650694b99 (patch)
tree3d87323f4f8187175b20f8e8966d3c8447161336 /arch/ppc/platforms
parentdad482c25698134b79c80694c81f0495019e0842 (diff)
[PATCH] ppc32: Add TQM85xx (8540/8541/8555/8560) board support
This patch adds support for the TQ Components TQM85xx modules. Currently the modules TQM8540/8541/8555/8560 are supported. Signed-off-by: Stefan Roese <sr@denx.de> Signed-off-by: Kumar Gala <galak@kernel.crashing.org> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/ppc/platforms')
-rw-r--r--arch/ppc/platforms/85xx/Kconfig28
-rw-r--r--arch/ppc/platforms/85xx/Makefile4
-rw-r--r--arch/ppc/platforms/85xx/tqm85xx.c419
-rw-r--r--arch/ppc/platforms/85xx/tqm85xx.h56
4 files changed, 503 insertions, 4 deletions
diff --git a/arch/ppc/platforms/85xx/Kconfig b/arch/ppc/platforms/85xx/Kconfig
index c5bc2821d991..7ddd331a7145 100644
--- a/arch/ppc/platforms/85xx/Kconfig
+++ b/arch/ppc/platforms/85xx/Kconfig
@@ -39,7 +39,7 @@ config MPC8560_ADS
39config SBC8560 39config SBC8560
40 bool "WindRiver PowerQUICC III SBC8560" 40 bool "WindRiver PowerQUICC III SBC8560"
41 help 41 help
42 This option enables support for the WindRiver PowerQUICC III 42 This option enables support for the WindRiver PowerQUICC III
43 SBC8560 board. 43 SBC8560 board.
44 44
45config STX_GP3 45config STX_GP3
@@ -48,6 +48,26 @@ config STX_GP3
48 This option enables support for the Silicon Turnkey Express GP3 48 This option enables support for the Silicon Turnkey Express GP3
49 board. 49 board.
50 50
51config TQM8540
52 bool "TQ Components TQM8540"
53 help
54 This option enablese support for the TQ Components TQM8540 board.
55
56config TQM8541
57 bool "TQ Components TQM8541"
58 help
59 This option enablese support for the TQ Components TQM8541 board.
60
61config TQM8555
62 bool "TQ Components TQM8555"
63 help
64 This option enablese support for the TQ Components TQM8555 board.
65
66config TQM8560
67 bool "TQ Components TQM8560"
68 help
69 This option enablese support for the TQ Components TQM8560 board.
70
51endchoice 71endchoice
52 72
53# It's often necessary to know the specific 85xx processor type. 73# It's often necessary to know the specific 85xx processor type.
@@ -55,7 +75,7 @@ endchoice
55# don't need to ask more redundant questions. 75# don't need to ask more redundant questions.
56config MPC8540 76config MPC8540
57 bool 77 bool
58 depends on MPC8540_ADS 78 depends on MPC8540_ADS || TQM8540
59 default y 79 default y
60 80
61config MPC8548 81config MPC8548
@@ -65,12 +85,12 @@ config MPC8548
65 85
66config MPC8555 86config MPC8555
67 bool 87 bool
68 depends on MPC8555_CDS 88 depends on MPC8555_CDS || TQM8541 || TQM8555
69 default y 89 default y
70 90
71config MPC8560 91config MPC8560
72 bool 92 bool
73 depends on SBC8560 || MPC8560_ADS || STX_GP3 93 depends on SBC8560 || MPC8560_ADS || STX_GP3 || TQM8560
74 default y 94 default y
75 95
76config 85xx_PCI2 96config 85xx_PCI2
diff --git a/arch/ppc/platforms/85xx/Makefile b/arch/ppc/platforms/85xx/Makefile
index efdf813108f2..6c4753c144d3 100644
--- a/arch/ppc/platforms/85xx/Makefile
+++ b/arch/ppc/platforms/85xx/Makefile
@@ -7,3 +7,7 @@ obj-$(CONFIG_MPC8555_CDS) += mpc85xx_cds_common.o
7obj-$(CONFIG_MPC8560_ADS) += mpc85xx_ads_common.o mpc8560_ads.o 7obj-$(CONFIG_MPC8560_ADS) += mpc85xx_ads_common.o mpc8560_ads.o
8obj-$(CONFIG_SBC8560) += sbc85xx.o sbc8560.o 8obj-$(CONFIG_SBC8560) += sbc85xx.o sbc8560.o
9obj-$(CONFIG_STX_GP3) += stx_gp3.o 9obj-$(CONFIG_STX_GP3) += stx_gp3.o
10obj-$(CONFIG_TQM8540) += tqm85xx.o
11obj-$(CONFIG_TQM8541) += tqm85xx.o
12obj-$(CONFIG_TQM8555) += tqm85xx.o
13obj-$(CONFIG_TQM8560) += tqm85xx.o
diff --git a/arch/ppc/platforms/85xx/tqm85xx.c b/arch/ppc/platforms/85xx/tqm85xx.c
new file mode 100644
index 000000000000..c6dfd8f0f9df
--- /dev/null
+++ b/arch/ppc/platforms/85xx/tqm85xx.c
@@ -0,0 +1,419 @@
1/*
2 * arch/ppc/platforms/85xx/tqm85xx.c
3 *
4 * TQM85xx (40/41/55/60) board specific routines
5 *
6 * Copyright (c) 2005 DENX Software Engineering
7 * Stefan Roese <sr@denx.de>
8 *
9 * Based on original work by
10 * Kumar Gala <galak@kernel.crashing.org>
11 * Copyright 2004 Freescale Semiconductor Inc.
12 *
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License as published by the
15 * Free Software Foundation; either version 2 of the License, or (at your
16 * option) any later version.
17 */
18
19#include <linux/config.h>
20#include <linux/stddef.h>
21#include <linux/kernel.h>
22#include <linux/init.h>
23#include <linux/errno.h>
24#include <linux/reboot.h>
25#include <linux/pci.h>
26#include <linux/kdev_t.h>
27#include <linux/major.h>
28#include <linux/console.h>
29#include <linux/delay.h>
30#include <linux/seq_file.h>
31#include <linux/root_dev.h>
32#include <linux/serial.h>
33#include <linux/tty.h> /* for linux/serial_core.h */
34#include <linux/serial_core.h>
35#include <linux/initrd.h>
36#include <linux/module.h>
37#include <linux/fsl_devices.h>
38
39#include <asm/system.h>
40#include <asm/pgtable.h>
41#include <asm/page.h>
42#include <asm/atomic.h>
43#include <asm/time.h>
44#include <asm/io.h>
45#include <asm/machdep.h>
46#include <asm/open_pic.h>
47#include <asm/bootinfo.h>
48#include <asm/pci-bridge.h>
49#include <asm/mpc85xx.h>
50#include <asm/irq.h>
51#include <asm/immap_85xx.h>
52#include <asm/kgdb.h>
53#include <asm/ppc_sys.h>
54#include <asm/cpm2.h>
55#include <mm/mmu_decl.h>
56
57#include <syslib/ppc85xx_setup.h>
58#include <syslib/cpm2_pic.h>
59#include <syslib/ppc85xx_common.h>
60#include <syslib/ppc85xx_rio.h>
61
62#ifndef CONFIG_PCI
63unsigned long isa_io_base = 0;
64unsigned long isa_mem_base = 0;
65#endif
66
67
68extern unsigned long total_memory; /* in mm/init */
69
70unsigned char __res[sizeof (bd_t)];
71
72/* Internal interrupts are all Level Sensitive, and Positive Polarity */
73static u_char tqm85xx_openpic_initsenses[] __initdata = {
74 MPC85XX_INTERNAL_IRQ_SENSES,
75 0x0, /* External 0: */
76 0x0, /* External 1: */
77#if defined(CONFIG_PCI)
78 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* External 2: PCI INTA */
79 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* External 3: PCI INTB */
80#else
81 0x0, /* External 2: */
82 0x0, /* External 3: */
83#endif
84 0x0, /* External 4: */
85 0x0, /* External 5: */
86 0x0, /* External 6: */
87 0x0, /* External 7: */
88 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* External 8: PHY */
89 0x0, /* External 9: */
90 0x0, /* External 10: */
91 0x0, /* External 11: */
92};
93
94static const char *GFAR_PHY_0 = "phy0:2";
95static const char *GFAR_PHY_1 = "phy0:1";
96#ifdef CONFIG_MPC8540
97static const char *GFAR_PHY_3 = "phy0:3";
98#endif
99
100/* ************************************************************************
101 *
102 * Setup the architecture
103 *
104 */
105static void __init
106tqm85xx_setup_arch(void)
107{
108 bd_t *binfo = (bd_t *) __res;
109 unsigned int freq;
110 struct gianfar_platform_data *pdata;
111 struct gianfar_mdio_data *mdata;
112
113#ifdef CONFIG_MPC8560
114 cpm2_reset();
115#endif
116
117 /* get the core frequency */
118 freq = binfo->bi_intfreq;
119
120 if (ppc_md.progress)
121 ppc_md.progress("tqm85xx_setup_arch()", 0);
122
123 /* Set loops_per_jiffy to a half-way reasonable value,
124 for use until calibrate_delay gets called. */
125 loops_per_jiffy = freq / HZ;
126
127#ifdef CONFIG_PCI
128 /* setup PCI host bridges */
129 mpc85xx_setup_hose();
130#endif
131
132#ifndef CONFIG_MPC8560
133#if defined(CONFIG_SERIAL_8250)
134 mpc85xx_early_serial_map();
135#endif
136
137#ifdef CONFIG_SERIAL_TEXT_DEBUG
138 /* Invalidate the entry we stole earlier the serial ports
139 * should be properly mapped */
140 invalidate_tlbcam_entry(num_tlbcam_entries - 1);
141#endif
142#endif /* CONFIG_MPC8560 */
143
144 /* setup the board related info for the MDIO bus */
145 mdata = (struct gianfar_mdio_data *) ppc_sys_get_pdata(MPC85xx_MDIO);
146
147 mdata->irq[0] = MPC85xx_IRQ_EXT8;
148 mdata->irq[1] = MPC85xx_IRQ_EXT8;
149 mdata->irq[2] = -1;
150 mdata->irq[3] = MPC85xx_IRQ_EXT8;
151 mdata->irq[31] = -1;
152 mdata->paddr += binfo->bi_immr_base;
153
154 /* setup the board related information for the enet controllers */
155 pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1);
156 if (pdata) {
157 pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
158 pdata->bus_id = GFAR_PHY_0;
159 memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6);
160 }
161
162 pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2);
163 if (pdata) {
164 pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
165 pdata->bus_id = GFAR_PHY_1;
166 memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6);
167 }
168
169#ifdef CONFIG_MPC8540
170 pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_FEC);
171 if (pdata) {
172 pdata->board_flags = 0;
173 pdata->bus_id = GFAR_PHY_3;
174 memcpy(pdata->mac_addr, binfo->bi_enet2addr, 6);
175 }
176#endif
177
178#ifdef CONFIG_BLK_DEV_INITRD
179 if (initrd_start)
180 ROOT_DEV = Root_RAM0;
181 else
182#endif
183#ifdef CONFIG_ROOT_NFS
184 ROOT_DEV = Root_NFS;
185#else
186 ROOT_DEV = Root_HDA1;
187#endif
188}
189
190#ifdef CONFIG_MPC8560
191static irqreturn_t cpm2_cascade(int irq, void *dev_id, struct pt_regs *regs)
192{
193 while ((irq = cpm2_get_irq(regs)) >= 0)
194 __do_IRQ(irq, regs);
195 return IRQ_HANDLED;
196}
197
198static struct irqaction cpm2_irqaction = {
199 .handler = cpm2_cascade,
200 .flags = SA_INTERRUPT,
201 .mask = CPU_MASK_NONE,
202 .name = "cpm2_cascade",
203};
204#endif /* CONFIG_MPC8560 */
205
206void __init
207tqm85xx_init_IRQ(void)
208{
209 bd_t *binfo = (bd_t *) __res;
210
211 /* Determine the Physical Address of the OpenPIC regs */
212 phys_addr_t OpenPIC_PAddr =
213 binfo->bi_immr_base + MPC85xx_OPENPIC_OFFSET;
214 OpenPIC_Addr = ioremap(OpenPIC_PAddr, MPC85xx_OPENPIC_SIZE);
215 OpenPIC_InitSenses = tqm85xx_openpic_initsenses;
216 OpenPIC_NumInitSenses = sizeof (tqm85xx_openpic_initsenses);
217
218 /* Skip reserved space and internal sources */
219 openpic_set_sources(0, 32, OpenPIC_Addr + 0x10200);
220
221 /* Map PIC IRQs 0-11 */
222 openpic_set_sources(48, 12, OpenPIC_Addr + 0x10000);
223
224 /* we let openpic interrupts starting from an offset, to
225 * leave space for cascading interrupts underneath.
226 */
227 openpic_init(MPC85xx_OPENPIC_IRQ_OFFSET);
228
229#ifdef CONFIG_MPC8560
230 /* Setup CPM2 PIC */
231 cpm2_init_IRQ();
232
233 setup_irq(MPC85xx_IRQ_CPM, &cpm2_irqaction);
234#endif /* CONFIG_MPC8560 */
235
236 return;
237}
238
239int tqm85xx_show_cpuinfo(struct seq_file *m)
240{
241 uint pvid, svid, phid1;
242 uint memsize = total_memory;
243 bd_t *binfo = (bd_t *) __res;
244 unsigned int freq;
245
246 /* get the core frequency */
247 freq = binfo->bi_intfreq;
248
249 pvid = mfspr(SPRN_PVR);
250 svid = mfspr(SPRN_SVR);
251
252 seq_printf(m, "Vendor\t\t: TQ Components\n");
253 seq_printf(m, "Machine\t\t: TQM%s\n", cur_ppc_sys_spec->ppc_sys_name);
254 seq_printf(m, "clock\t\t: %dMHz\n", freq / 1000000);
255 seq_printf(m, "PVR\t\t: 0x%x\n", pvid);
256 seq_printf(m, "SVR\t\t: 0x%x\n", svid);
257
258 /* Display cpu Pll setting */
259 phid1 = mfspr(SPRN_HID1);
260 seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f));
261
262 /* Display the amount of memory */
263 seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024));
264
265 return 0;
266}
267
268#if defined(CONFIG_I2C) && defined(CONFIG_SENSORS_DS1337)
269extern ulong ds1337_get_rtc_time(void);
270extern int ds1337_set_rtc_time(unsigned long nowtime);
271
272static int __init
273tqm85xx_rtc_hookup(void)
274{
275 struct timespec tv;
276
277 ppc_md.set_rtc_time = ds1337_set_rtc_time;
278 ppc_md.get_rtc_time = ds1337_get_rtc_time;
279
280 tv.tv_nsec = 0;
281 tv.tv_sec = (ppc_md.get_rtc_time)();
282 do_settimeofday(&tv);
283
284 return 0;
285}
286late_initcall(tqm85xx_rtc_hookup);
287#endif
288
289#ifdef CONFIG_PCI
290/*
291 * interrupt routing
292 */
293int mpc85xx_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
294{
295 static char pci_irq_table[][4] =
296 /*
297 * PCI IDSEL/INTPIN->INTLINE
298 * A B C D
299 */
300 {
301 {PIRQA, PIRQB, 0, 0},
302 };
303
304 const long min_idsel = 0x1c, max_idsel = 0x1c, irqs_per_slot = 4;
305 return PCI_IRQ_TABLE_LOOKUP;
306}
307
308int mpc85xx_exclude_device(u_char bus, u_char devfn)
309{
310 if (bus == 0 && PCI_SLOT(devfn) == 0)
311 return PCIBIOS_DEVICE_NOT_FOUND;
312 else
313 return PCIBIOS_SUCCESSFUL;
314}
315
316#endif /* CONFIG_PCI */
317
318#ifdef CONFIG_RAPIDIO
319void platform_rio_init(void)
320{
321 /* 512MB RIO LAW at 0xc0000000 */
322 mpc85xx_rio_setup(0xc0000000, 0x20000000);
323}
324#endif /* CONFIG_RAPIDIO */
325
326/* ************************************************************************ */
327void __init
328platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
329 unsigned long r6, unsigned long r7)
330{
331 /* parse_bootinfo must always be called first */
332 parse_bootinfo(find_bootinfo());
333
334 /*
335 * If we were passed in a board information, copy it into the
336 * residual data area.
337 */
338 if (r3) {
339 memcpy((void *) __res, (void *) (r3 + KERNELBASE),
340 sizeof (bd_t));
341 }
342
343#if defined(CONFIG_SERIAL_TEXT_DEBUG) && !defined(CONFIG_MPC8560)
344 {
345 bd_t *binfo = (bd_t *) __res;
346 struct uart_port p;
347
348 /* Use the last TLB entry to map CCSRBAR to allow access to DUART regs */
349 settlbcam(num_tlbcam_entries - 1, binfo->bi_immr_base,
350 binfo->bi_immr_base, MPC85xx_CCSRBAR_SIZE, _PAGE_IO, 0);
351
352 memset(&p, 0, sizeof (p));
353 p.iotype = SERIAL_IO_MEM;
354 p.membase = (void *) binfo->bi_immr_base + MPC85xx_UART0_OFFSET;
355 p.uartclk = binfo->bi_busfreq;
356
357 gen550_init(0, &p);
358
359 memset(&p, 0, sizeof (p));
360 p.iotype = SERIAL_IO_MEM;
361 p.membase = (void *) binfo->bi_immr_base + MPC85xx_UART1_OFFSET;
362 p.uartclk = binfo->bi_busfreq;
363
364 gen550_init(1, &p);
365 }
366#endif
367
368#if defined(CONFIG_BLK_DEV_INITRD)
369 /*
370 * If the init RAM disk has been configured in, and there's a valid
371 * starting address for it, set it up.
372 */
373 if (r4) {
374 initrd_start = r4 + KERNELBASE;
375 initrd_end = r5 + KERNELBASE;
376 }
377#endif /* CONFIG_BLK_DEV_INITRD */
378
379 /* Copy the kernel command line arguments to a safe place. */
380
381 if (r6) {
382 *(char *) (r7 + KERNELBASE) = 0;
383 strcpy(cmd_line, (char *) (r6 + KERNELBASE));
384 }
385
386 identify_ppc_sys_by_id(mfspr(SPRN_SVR));
387
388 /* setup the PowerPC module struct */
389 ppc_md.setup_arch = tqm85xx_setup_arch;
390 ppc_md.show_cpuinfo = tqm85xx_show_cpuinfo;
391
392 ppc_md.init_IRQ = tqm85xx_init_IRQ;
393 ppc_md.get_irq = openpic_get_irq;
394
395 ppc_md.restart = mpc85xx_restart;
396 ppc_md.power_off = mpc85xx_power_off;
397 ppc_md.halt = mpc85xx_halt;
398
399 ppc_md.find_end_of_memory = mpc85xx_find_end_of_memory;
400
401 ppc_md.time_init = NULL;
402 ppc_md.set_rtc_time = NULL;
403 ppc_md.get_rtc_time = NULL;
404 ppc_md.calibrate_decr = mpc85xx_calibrate_decr;
405
406#ifndef CONFIG_MPC8560
407#if defined(CONFIG_SERIAL_8250) && defined(CONFIG_SERIAL_TEXT_DEBUG)
408 ppc_md.progress = gen550_progress;
409#endif /* CONFIG_SERIAL_8250 && CONFIG_SERIAL_TEXT_DEBUG */
410#if defined(CONFIG_SERIAL_8250) && defined(CONFIG_KGDB)
411 ppc_md.early_serial_map = mpc85xx_early_serial_map;
412#endif /* CONFIG_SERIAL_8250 && CONFIG_KGDB */
413#endif /* CONFIG_MPC8560 */
414
415 if (ppc_md.progress)
416 ppc_md.progress("tqm85xx_init(): exit", 0);
417
418 return;
419}
diff --git a/arch/ppc/platforms/85xx/tqm85xx.h b/arch/ppc/platforms/85xx/tqm85xx.h
new file mode 100644
index 000000000000..3775eb363fde
--- /dev/null
+++ b/arch/ppc/platforms/85xx/tqm85xx.h
@@ -0,0 +1,56 @@
1/*
2 * arch/ppc/platforms/85xx/tqm85xx.h
3 *
4 * TQM85xx (40/41/55/60) board definitions
5 *
6 * Copyright (c) 2005 DENX Software Engineering
7 * Stefan Roese <sr@denx.de>
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
16#ifndef __MACH_TQM85XX_H
17#define __MACH_TQM85XX_H
18
19#include <linux/config.h>
20#include <linux/init.h>
21#include <asm/ppcboot.h>
22
23#define BOARD_CCSRBAR ((uint)0xe0000000)
24#define CCSRBAR_SIZE ((uint)1024*1024)
25
26#define CPM_MAP_ADDR (CCSRBAR + MPC85xx_CPM_OFFSET)
27
28#define PCI_CFG_ADDR_OFFSET (0x8000)
29#define PCI_CFG_DATA_OFFSET (0x8004)
30
31/* PCI interrupt controller */
32#define PIRQA MPC85xx_IRQ_EXT2
33#define PIRQB MPC85xx_IRQ_EXT3
34
35#define MPC85XX_PCI1_LOWER_IO 0x00000000
36#define MPC85XX_PCI1_UPPER_IO 0x00ffffff
37
38#define MPC85XX_PCI1_LOWER_MEM 0x80000000
39#define MPC85XX_PCI1_UPPER_MEM 0x9fffffff
40
41#define MPC85XX_PCI1_IO_BASE 0xe2000000
42#define MPC85XX_PCI1_MEM_OFFSET 0x00000000
43
44#define MPC85XX_PCI1_IO_SIZE 0x01000000
45
46#define BASE_BAUD 115200
47
48extern void mpc85xx_setup_hose(void) __init;
49extern void mpc85xx_restart(char *cmd);
50extern void mpc85xx_power_off(void);
51extern void mpc85xx_halt(void);
52extern void mpc85xx_init_IRQ(void) __init;
53extern unsigned long mpc85xx_find_end_of_memory(void) __init;
54extern void mpc85xx_calibrate_decr(void) __init;
55
56#endif /* __MACH_TQM85XX_H */