aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/82xx
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/platforms/82xx')
-rw-r--r--arch/powerpc/platforms/82xx/Kconfig24
-rw-r--r--arch/powerpc/platforms/82xx/Makefile6
-rw-r--r--arch/powerpc/platforms/82xx/m82xx_pci.h2
-rw-r--r--arch/powerpc/platforms/82xx/mpc8272_ads.c196
-rw-r--r--arch/powerpc/platforms/82xx/mpc82xx.c110
-rw-r--r--arch/powerpc/platforms/82xx/mpc82xx_ads.c641
-rw-r--r--arch/powerpc/platforms/82xx/pq2.c82
-rw-r--r--arch/powerpc/platforms/82xx/pq2.h20
-rw-r--r--arch/powerpc/platforms/82xx/pq2ads-pci-pic.c195
-rw-r--r--arch/powerpc/platforms/82xx/pq2ads.h9
-rw-r--r--arch/powerpc/platforms/82xx/pq2fads.c198
11 files changed, 715 insertions, 768 deletions
diff --git a/arch/powerpc/platforms/82xx/Kconfig b/arch/powerpc/platforms/82xx/Kconfig
index 89fde43895c5..541fbb815631 100644
--- a/arch/powerpc/platforms/82xx/Kconfig
+++ b/arch/powerpc/platforms/82xx/Kconfig
@@ -1,17 +1,30 @@
1choice 1choice
2 prompt "82xx Board Type" 2 prompt "82xx Board Type"
3 depends on PPC_82xx 3 depends on PPC_82xx
4 default MPC82xx_ADS 4 default MPC8272_ADS
5 5
6config MPC82xx_ADS 6config MPC8272_ADS
7 bool "Freescale MPC82xx ADS" 7 bool "Freescale MPC8272 ADS"
8 select DEFAULT_UIMAGE 8 select DEFAULT_UIMAGE
9 select PQ2ADS 9 select PQ2ADS
10 select 8272 10 select 8272
11 select 8260 11 select 8260
12 select FSL_SOC 12 select FSL_SOC
13 select PQ2_ADS_PCI_PIC if PCI
14 select PPC_CPM_NEW_BINDING
13 help 15 help
14 This option enables support for the MPC8272 ADS board 16 This option enables support for the MPC8272 ADS board
17
18config PQ2FADS
19 bool "Freescale PQ2FADS"
20 select DEFAULT_UIMAGE
21 select PQ2ADS
22 select 8260
23 select FSL_SOC
24 select PQ2_ADS_PCI_PIC if PCI
25 select PPC_CPM_NEW_BINDING
26 help
27 This option enables support for the PQ2FADS board
15 28
16endchoice 29endchoice
17 30
@@ -34,3 +47,6 @@ config 8272
34 help 47 help
35 The MPC8272 CPM has a different internal dpram setup than other CPM2 48 The MPC8272 CPM has a different internal dpram setup than other CPM2
36 devices 49 devices
50
51config PQ2_ADS_PCI_PIC
52 bool
diff --git a/arch/powerpc/platforms/82xx/Makefile b/arch/powerpc/platforms/82xx/Makefile
index d9fd4c84d2e0..68c8b0c9772b 100644
--- a/arch/powerpc/platforms/82xx/Makefile
+++ b/arch/powerpc/platforms/82xx/Makefile
@@ -1,5 +1,7 @@
1# 1#
2# Makefile for the PowerPC 82xx linux kernel. 2# Makefile for the PowerPC 82xx linux kernel.
3# 3#
4obj-$(CONFIG_PPC_82xx) += mpc82xx.o 4obj-$(CONFIG_MPC8272_ADS) += mpc8272_ads.o
5obj-$(CONFIG_MPC82xx_ADS) += mpc82xx_ads.o 5obj-$(CONFIG_CPM2) += pq2.o
6obj-$(CONFIG_PQ2_ADS_PCI_PIC) += pq2ads-pci-pic.o
7obj-$(CONFIG_PQ2FADS) += pq2fads.o
diff --git a/arch/powerpc/platforms/82xx/m82xx_pci.h b/arch/powerpc/platforms/82xx/m82xx_pci.h
index 9cd8893b5a32..65e38a7ff48f 100644
--- a/arch/powerpc/platforms/82xx/m82xx_pci.h
+++ b/arch/powerpc/platforms/82xx/m82xx_pci.h
@@ -8,8 +8,6 @@
8 * 2 of the License, or (at your option) any later version. 8 * 2 of the License, or (at your option) any later version.
9 */ 9 */
10 10
11#include <asm/m8260_pci.h>
12
13#define SIU_INT_IRQ1 ((uint)0x13 + CPM_IRQ_OFFSET) 11#define SIU_INT_IRQ1 ((uint)0x13 + CPM_IRQ_OFFSET)
14 12
15#ifndef _IO_BASE 13#ifndef _IO_BASE
diff --git a/arch/powerpc/platforms/82xx/mpc8272_ads.c b/arch/powerpc/platforms/82xx/mpc8272_ads.c
new file mode 100644
index 000000000000..fd83440eb287
--- /dev/null
+++ b/arch/powerpc/platforms/82xx/mpc8272_ads.c
@@ -0,0 +1,196 @@
1/*
2 * MPC8272 ADS board support
3 *
4 * Copyright 2007 Freescale Semiconductor, Inc.
5 * Author: Scott Wood <scottwood@freescale.com>
6 *
7 * Based on code by Vitaly Bordug <vbordug@ru.mvista.com>
8 * Copyright (c) 2006 MontaVista Software, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 */
15
16#include <linux/init.h>
17#include <linux/interrupt.h>
18#include <linux/fsl_devices.h>
19#include <linux/of_platform.h>
20#include <linux/io.h>
21
22#include <asm/cpm2.h>
23#include <asm/udbg.h>
24#include <asm/machdep.h>
25#include <asm/time.h>
26
27#include <platforms/82xx/pq2.h>
28
29#include <sysdev/fsl_soc.h>
30#include <sysdev/cpm2_pic.h>
31
32#include "pq2ads.h"
33#include "pq2.h"
34
35static void __init mpc8272_ads_pic_init(void)
36{
37 struct device_node *np = of_find_compatible_node(NULL, NULL,
38 "fsl,cpm2-pic");
39 if (!np) {
40 printk(KERN_ERR "PIC init: can not find fsl,cpm2-pic node\n");
41 return;
42 }
43
44 cpm2_pic_init(np);
45 of_node_put(np);
46
47 /* Initialize stuff for the 82xx CPLD IC and install demux */
48 pq2ads_pci_init_irq();
49}
50
51struct cpm_pin {
52 int port, pin, flags;
53};
54
55static struct cpm_pin mpc8272_ads_pins[] = {
56 /* SCC1 */
57 {3, 30, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY},
58 {3, 31, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
59
60 /* SCC4 */
61 {3, 21, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
62 {3, 22, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
63
64 /* FCC1 */
65 {0, 14, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
66 {0, 15, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
67 {0, 16, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
68 {0, 17, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
69 {0, 18, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
70 {0, 19, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
71 {0, 20, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
72 {0, 21, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
73 {0, 26, CPM_PIN_INPUT | CPM_PIN_SECONDARY},
74 {0, 27, CPM_PIN_INPUT | CPM_PIN_SECONDARY},
75 {0, 28, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY},
76 {0, 29, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY},
77 {0, 30, CPM_PIN_INPUT | CPM_PIN_SECONDARY},
78 {0, 31, CPM_PIN_INPUT | CPM_PIN_SECONDARY},
79 {2, 21, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
80 {2, 22, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
81
82 /* FCC2 */
83 {1, 18, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
84 {1, 19, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
85 {1, 20, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
86 {1, 21, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
87 {1, 22, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
88 {1, 23, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
89 {1, 24, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
90 {1, 25, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
91 {1, 26, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
92 {1, 27, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
93 {1, 28, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
94 {1, 29, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY},
95 {1, 30, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
96 {1, 31, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
97 {2, 16, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
98 {2, 17, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
99};
100
101static void __init init_ioports(void)
102{
103 int i;
104
105 for (i = 0; i < ARRAY_SIZE(mpc8272_ads_pins); i++) {
106 struct cpm_pin *pin = &mpc8272_ads_pins[i];
107 cpm2_set_pin(pin->port, pin->pin, pin->flags);
108 }
109
110 cpm2_clk_setup(CPM_CLK_SCC1, CPM_BRG1, CPM_CLK_RX);
111 cpm2_clk_setup(CPM_CLK_SCC1, CPM_BRG1, CPM_CLK_TX);
112 cpm2_clk_setup(CPM_CLK_SCC4, CPM_BRG4, CPM_CLK_RX);
113 cpm2_clk_setup(CPM_CLK_SCC4, CPM_BRG4, CPM_CLK_TX);
114 cpm2_clk_setup(CPM_CLK_FCC1, CPM_CLK11, CPM_CLK_RX);
115 cpm2_clk_setup(CPM_CLK_FCC1, CPM_CLK10, CPM_CLK_TX);
116 cpm2_clk_setup(CPM_CLK_FCC2, CPM_CLK15, CPM_CLK_RX);
117 cpm2_clk_setup(CPM_CLK_FCC2, CPM_CLK16, CPM_CLK_TX);
118}
119
120static void __init mpc8272_ads_setup_arch(void)
121{
122 struct device_node *np;
123 __be32 __iomem *bcsr;
124
125 if (ppc_md.progress)
126 ppc_md.progress("mpc8272_ads_setup_arch()", 0);
127
128 cpm2_reset();
129
130 np = of_find_compatible_node(NULL, NULL, "fsl,mpc8272ads-bcsr");
131 if (!np) {
132 printk(KERN_ERR "No bcsr in device tree\n");
133 return;
134 }
135
136 bcsr = of_iomap(np, 0);
137 if (!bcsr) {
138 printk(KERN_ERR "Cannot map BCSR registers\n");
139 return;
140 }
141
142 of_node_put(np);
143
144 clrbits32(&bcsr[1], BCSR1_RS232_EN1 | BCSR1_RS232_EN2 | BCSR1_FETHIEN);
145 setbits32(&bcsr[1], BCSR1_FETH_RST);
146
147 clrbits32(&bcsr[3], BCSR3_FETHIEN2);
148 setbits32(&bcsr[3], BCSR3_FETH2_RST);
149
150 iounmap(bcsr);
151
152 init_ioports();
153 pq2_init_pci();
154
155 if (ppc_md.progress)
156 ppc_md.progress("mpc8272_ads_setup_arch(), finish", 0);
157}
158
159static struct of_device_id __initdata of_bus_ids[] = {
160 { .name = "soc", },
161 { .name = "cpm", },
162 { .name = "localbus", },
163 {},
164};
165
166static int __init declare_of_platform_devices(void)
167{
168 if (!machine_is(mpc8272_ads))
169 return 0;
170
171 /* Publish the QE devices */
172 of_platform_bus_probe(NULL, of_bus_ids, NULL);
173 return 0;
174}
175device_initcall(declare_of_platform_devices);
176
177/*
178 * Called very early, device-tree isn't unflattened
179 */
180static int __init mpc8272_ads_probe(void)
181{
182 unsigned long root = of_get_flat_dt_root();
183 return of_flat_dt_is_compatible(root, "fsl,mpc8272ads");
184}
185
186define_machine(mpc8272_ads)
187{
188 .name = "Freescale MPC8272 ADS",
189 .probe = mpc8272_ads_probe,
190 .setup_arch = mpc8272_ads_setup_arch,
191 .init_IRQ = mpc8272_ads_pic_init,
192 .get_irq = cpm2_get_irq,
193 .calibrate_decr = generic_calibrate_decr,
194 .restart = pq2_restart,
195 .progress = udbg_progress,
196};
diff --git a/arch/powerpc/platforms/82xx/mpc82xx.c b/arch/powerpc/platforms/82xx/mpc82xx.c
deleted file mode 100644
index cc9900d2e5ee..000000000000
--- a/arch/powerpc/platforms/82xx/mpc82xx.c
+++ /dev/null
@@ -1,110 +0,0 @@
1/*
2 * MPC82xx setup and early boot code plus other random bits.
3 *
4 * Author: Vitaly Bordug <vbordug@ru.mvista.com>
5 *
6 * Copyright (c) 2006 MontaVista Software, Inc.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 */
13
14#include <linux/stddef.h>
15#include <linux/kernel.h>
16#include <linux/init.h>
17#include <linux/errno.h>
18#include <linux/reboot.h>
19#include <linux/pci.h>
20#include <linux/interrupt.h>
21#include <linux/kdev_t.h>
22#include <linux/major.h>
23#include <linux/console.h>
24#include <linux/delay.h>
25#include <linux/seq_file.h>
26#include <linux/root_dev.h>
27#include <linux/initrd.h>
28#include <linux/module.h>
29#include <linux/fsl_devices.h>
30#include <linux/fs_uart_pd.h>
31
32#include <asm/system.h>
33#include <asm/pgtable.h>
34#include <asm/page.h>
35#include <asm/atomic.h>
36#include <asm/time.h>
37#include <asm/io.h>
38#include <asm/machdep.h>
39#include <asm/bootinfo.h>
40#include <asm/pci-bridge.h>
41#include <asm/mpc8260.h>
42#include <asm/irq.h>
43#include <mm/mmu_decl.h>
44#include <asm/prom.h>
45#include <asm/cpm2.h>
46#include <asm/udbg.h>
47#include <asm/i8259.h>
48#include <linux/fs_enet_pd.h>
49
50#include <sysdev/fsl_soc.h>
51#include <sysdev/cpm2_pic.h>
52
53#include "pq2ads.h"
54
55static int __init get_freq(char *name, unsigned long *val)
56{
57 struct device_node *cpu;
58 const unsigned int *fp;
59 int found = 0;
60
61 /* The cpu node should have timebase and clock frequency properties */
62 cpu = of_find_node_by_type(NULL, "cpu");
63
64 if (cpu) {
65 fp = of_get_property(cpu, name, NULL);
66 if (fp) {
67 found = 1;
68 *val = *fp;
69 }
70
71 of_node_put(cpu);
72 }
73
74 return found;
75}
76
77void __init m82xx_calibrate_decr(void)
78{
79 ppc_tb_freq = 125000000;
80 if (!get_freq("bus-frequency", &ppc_tb_freq)) {
81 printk(KERN_ERR "WARNING: Estimating decrementer frequency "
82 "(not found)\n");
83 }
84 ppc_tb_freq /= 4;
85 ppc_proc_freq = 1000000000;
86 if (!get_freq("clock-frequency", &ppc_proc_freq))
87 printk(KERN_ERR "WARNING: Estimating processor frequency"
88 "(not found)\n");
89}
90
91void mpc82xx_ads_show_cpuinfo(struct seq_file *m)
92{
93 uint pvid, svid, phid1;
94 uint memsize = total_memory;
95
96 pvid = mfspr(SPRN_PVR);
97 svid = mfspr(SPRN_SVR);
98
99 seq_printf(m, "Vendor\t\t: Freescale Semiconductor\n");
100 seq_printf(m, "Machine\t\t: %s\n", CPUINFO_MACHINE);
101 seq_printf(m, "PVR\t\t: 0x%x\n", pvid);
102 seq_printf(m, "SVR\t\t: 0x%x\n", svid);
103
104 /* Display cpu Pll setting */
105 phid1 = mfspr(SPRN_HID1);
106 seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f));
107
108 /* Display the amount of memory */
109 seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024));
110}
diff --git a/arch/powerpc/platforms/82xx/mpc82xx_ads.c b/arch/powerpc/platforms/82xx/mpc82xx_ads.c
deleted file mode 100644
index 2d1b05b9f8ef..000000000000
--- a/arch/powerpc/platforms/82xx/mpc82xx_ads.c
+++ /dev/null
@@ -1,641 +0,0 @@
1/*
2 * MPC82xx_ads setup and early boot code plus other random bits.
3 *
4 * Author: Vitaly Bordug <vbordug@ru.mvista.com>
5 * m82xx_restart fix by Wade Farnsworth <wfarnsworth@mvista.com>
6 *
7 * Copyright (c) 2006 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/stddef.h>
16#include <linux/kernel.h>
17#include <linux/init.h>
18#include <linux/errno.h>
19#include <linux/reboot.h>
20#include <linux/pci.h>
21#include <linux/interrupt.h>
22#include <linux/kdev_t.h>
23#include <linux/major.h>
24#include <linux/console.h>
25#include <linux/delay.h>
26#include <linux/seq_file.h>
27#include <linux/root_dev.h>
28#include <linux/initrd.h>
29#include <linux/module.h>
30#include <linux/fsl_devices.h>
31#include <linux/fs_uart_pd.h>
32
33#include <asm/system.h>
34#include <asm/pgtable.h>
35#include <asm/page.h>
36#include <asm/atomic.h>
37#include <asm/time.h>
38#include <asm/io.h>
39#include <asm/machdep.h>
40#include <asm/bootinfo.h>
41#include <asm/pci-bridge.h>
42#include <asm/mpc8260.h>
43#include <asm/irq.h>
44#include <mm/mmu_decl.h>
45#include <asm/prom.h>
46#include <asm/cpm2.h>
47#include <asm/udbg.h>
48#include <asm/i8259.h>
49#include <linux/fs_enet_pd.h>
50
51#include <sysdev/fsl_soc.h>
52#include <sysdev/cpm2_pic.h>
53
54#include "pq2ads.h"
55
56#ifdef CONFIG_PCI
57static uint pci_clk_frq;
58static struct {
59 unsigned long *pci_int_stat_reg;
60 unsigned long *pci_int_mask_reg;
61} pci_regs;
62
63static unsigned long pci_int_base;
64static struct irq_host *pci_pic_host;
65static struct device_node *pci_pic_node;
66#endif
67
68static void __init mpc82xx_ads_pic_init(void)
69{
70 struct device_node *np = of_find_compatible_node(NULL, "cpm-pic", "CPM2");
71 struct resource r;
72 cpm2_map_t *cpm_reg;
73
74 if (np == NULL) {
75 printk(KERN_ERR "PIC init: can not find cpm-pic node\n");
76 return;
77 }
78 if (of_address_to_resource(np, 0, &r)) {
79 printk(KERN_ERR "PIC init: invalid resource\n");
80 of_node_put(np);
81 return;
82 }
83 cpm2_pic_init(np);
84 of_node_put(np);
85
86 /* Initialize the default interrupt mapping priorities,
87 * in case the boot rom changed something on us.
88 */
89 cpm_reg = (cpm2_map_t *) ioremap(get_immrbase(), sizeof(cpm2_map_t));
90 cpm_reg->im_intctl.ic_siprr = 0x05309770;
91 iounmap(cpm_reg);
92#ifdef CONFIG_PCI
93 /* Initialize stuff for the 82xx CPLD IC and install demux */
94 m82xx_pci_init_irq();
95#endif
96}
97
98static void init_fcc1_ioports(struct fs_platform_info *fpi)
99{
100 struct io_port *io;
101 u32 tempval;
102 cpm2_map_t *immap = ioremap(get_immrbase(), sizeof(cpm2_map_t));
103 struct device_node *np;
104 struct resource r;
105 u32 *bcsr;
106
107 np = of_find_node_by_type(NULL, "memory");
108 if (!np) {
109 printk(KERN_INFO "No memory node in device tree\n");
110 return;
111 }
112 if (of_address_to_resource(np, 1, &r)) {
113 printk(KERN_INFO "No memory reg property [1] in devicetree\n");
114 return;
115 }
116 of_node_put(np);
117 bcsr = ioremap(r.start + 4, sizeof(u32));
118 io = &immap->im_ioport;
119
120 /* Enable the PHY */
121 clrbits32(bcsr, BCSR1_FETHIEN);
122 setbits32(bcsr, BCSR1_FETH_RST);
123
124 /* FCC1 pins are on port A/C. */
125 /* Configure port A and C pins for FCC1 Ethernet. */
126
127 tempval = in_be32(&io->iop_pdira);
128 tempval &= ~PA1_DIRA0;
129 tempval |= PA1_DIRA1;
130 out_be32(&io->iop_pdira, tempval);
131
132 tempval = in_be32(&io->iop_psora);
133 tempval &= ~PA1_PSORA0;
134 tempval |= PA1_PSORA1;
135 out_be32(&io->iop_psora, tempval);
136
137 setbits32(&io->iop_ppara, PA1_DIRA0 | PA1_DIRA1);
138
139 /* Alter clocks */
140 tempval = PC_CLK(fpi->clk_tx - 8) | PC_CLK(fpi->clk_rx - 8);
141
142 clrbits32(&io->iop_psorc, tempval);
143 clrbits32(&io->iop_pdirc, tempval);
144 setbits32(&io->iop_pparc, tempval);
145
146 cpm2_clk_setup(CPM_CLK_FCC1, fpi->clk_rx, CPM_CLK_RX);
147 cpm2_clk_setup(CPM_CLK_FCC1, fpi->clk_tx, CPM_CLK_TX);
148
149 iounmap(bcsr);
150 iounmap(immap);
151}
152
153static void init_fcc2_ioports(struct fs_platform_info *fpi)
154{
155 cpm2_map_t *immap = ioremap(get_immrbase(), sizeof(cpm2_map_t));
156 struct device_node *np;
157 struct resource r;
158 u32 *bcsr;
159
160 struct io_port *io;
161 u32 tempval;
162
163 np = of_find_node_by_type(NULL, "memory");
164 if (!np) {
165 printk(KERN_INFO "No memory node in device tree\n");
166 return;
167 }
168 if (of_address_to_resource(np, 1, &r)) {
169 printk(KERN_INFO "No memory reg property [1] in devicetree\n");
170 return;
171 }
172 of_node_put(np);
173 io = &immap->im_ioport;
174 bcsr = ioremap(r.start + 12, sizeof(u32));
175
176 /* Enable the PHY */
177 clrbits32(bcsr, BCSR3_FETHIEN2);
178 setbits32(bcsr, BCSR3_FETH2_RST);
179
180 /* FCC2 are port B/C. */
181 /* Configure port A and C pins for FCC2 Ethernet. */
182
183 tempval = in_be32(&io->iop_pdirb);
184 tempval &= ~PB2_DIRB0;
185 tempval |= PB2_DIRB1;
186 out_be32(&io->iop_pdirb, tempval);
187
188 tempval = in_be32(&io->iop_psorb);
189 tempval &= ~PB2_PSORB0;
190 tempval |= PB2_PSORB1;
191 out_be32(&io->iop_psorb, tempval);
192
193 setbits32(&io->iop_pparb, PB2_DIRB0 | PB2_DIRB1);
194
195 tempval = PC_CLK(fpi->clk_tx - 8) | PC_CLK(fpi->clk_rx - 8);
196
197 /* Alter clocks */
198 clrbits32(&io->iop_psorc, tempval);
199 clrbits32(&io->iop_pdirc, tempval);
200 setbits32(&io->iop_pparc, tempval);
201
202 cpm2_clk_setup(CPM_CLK_FCC2, fpi->clk_rx, CPM_CLK_RX);
203 cpm2_clk_setup(CPM_CLK_FCC2, fpi->clk_tx, CPM_CLK_TX);
204
205 iounmap(bcsr);
206 iounmap(immap);
207}
208
209void init_fcc_ioports(struct fs_platform_info *fpi)
210{
211 int fcc_no = fs_get_fcc_index(fpi->fs_no);
212
213 switch (fcc_no) {
214 case 0:
215 init_fcc1_ioports(fpi);
216 break;
217 case 1:
218 init_fcc2_ioports(fpi);
219 break;
220 default:
221 printk(KERN_ERR "init_fcc_ioports: invalid FCC number\n");
222 return;
223 }
224}
225
226static void init_scc1_uart_ioports(struct fs_uart_platform_info *data)
227{
228 cpm2_map_t *immap = ioremap(get_immrbase(), sizeof(cpm2_map_t));
229
230 /* SCC1 is only on port D */
231 setbits32(&immap->im_ioport.iop_ppard, 0x00000003);
232 clrbits32(&immap->im_ioport.iop_psord, 0x00000001);
233 setbits32(&immap->im_ioport.iop_psord, 0x00000002);
234 clrbits32(&immap->im_ioport.iop_pdird, 0x00000001);
235 setbits32(&immap->im_ioport.iop_pdird, 0x00000002);
236
237 clrbits32(&immap->im_cpmux.cmx_scr, (0x00000007 << (4 - data->clk_tx)));
238 clrbits32(&immap->im_cpmux.cmx_scr, (0x00000038 << (4 - data->clk_rx)));
239 setbits32(&immap->im_cpmux.cmx_scr,
240 ((data->clk_tx - 1) << (4 - data->clk_tx)));
241 setbits32(&immap->im_cpmux.cmx_scr,
242 ((data->clk_rx - 1) << (4 - data->clk_rx)));
243
244 iounmap(immap);
245}
246
247static void init_scc4_uart_ioports(struct fs_uart_platform_info *data)
248{
249 cpm2_map_t *immap = ioremap(get_immrbase(), sizeof(cpm2_map_t));
250
251 setbits32(&immap->im_ioport.iop_ppard, 0x00000600);
252 clrbits32(&immap->im_ioport.iop_psord, 0x00000600);
253 clrbits32(&immap->im_ioport.iop_pdird, 0x00000200);
254 setbits32(&immap->im_ioport.iop_pdird, 0x00000400);
255
256 clrbits32(&immap->im_cpmux.cmx_scr, (0x00000007 << (4 - data->clk_tx)));
257 clrbits32(&immap->im_cpmux.cmx_scr, (0x00000038 << (4 - data->clk_rx)));
258 setbits32(&immap->im_cpmux.cmx_scr,
259 ((data->clk_tx - 1) << (4 - data->clk_tx)));
260 setbits32(&immap->im_cpmux.cmx_scr,
261 ((data->clk_rx - 1) << (4 - data->clk_rx)));
262
263 iounmap(immap);
264}
265
266void init_scc_ioports(struct fs_uart_platform_info *data)
267{
268 int scc_no = fs_get_scc_index(data->fs_no);
269
270 switch (scc_no) {
271 case 0:
272 init_scc1_uart_ioports(data);
273 data->brg = data->clk_rx;
274 break;
275 case 3:
276 init_scc4_uart_ioports(data);
277 data->brg = data->clk_rx;
278 break;
279 default:
280 printk(KERN_ERR "init_scc_ioports: invalid SCC number\n");
281 return;
282 }
283}
284
285void __init m82xx_board_setup(void)
286{
287 cpm2_map_t *immap = ioremap(get_immrbase(), sizeof(cpm2_map_t));
288 struct device_node *np;
289 struct resource r;
290 u32 *bcsr;
291
292 np = of_find_node_by_type(NULL, "memory");
293 if (!np) {
294 printk(KERN_INFO "No memory node in device tree\n");
295 return;
296 }
297 if (of_address_to_resource(np, 1, &r)) {
298 printk(KERN_INFO "No memory reg property [1] in devicetree\n");
299 return;
300 }
301 of_node_put(np);
302 bcsr = ioremap(r.start + 4, sizeof(u32));
303 /* Enable the 2nd UART port */
304 clrbits32(bcsr, BCSR1_RS232_EN2);
305
306#ifdef CONFIG_SERIAL_CPM_SCC1
307 clrbits32((u32 *) & immap->im_scc[0].scc_sccm,
308 UART_SCCM_TX | UART_SCCM_RX);
309 clrbits32((u32 *) & immap->im_scc[0].scc_gsmrl,
310 SCC_GSMRL_ENR | SCC_GSMRL_ENT);
311#endif
312
313#ifdef CONFIG_SERIAL_CPM_SCC2
314 clrbits32((u32 *) & immap->im_scc[1].scc_sccm,
315 UART_SCCM_TX | UART_SCCM_RX);
316 clrbits32((u32 *) & immap->im_scc[1].scc_gsmrl,
317 SCC_GSMRL_ENR | SCC_GSMRL_ENT);
318#endif
319
320#ifdef CONFIG_SERIAL_CPM_SCC3
321 clrbits32((u32 *) & immap->im_scc[2].scc_sccm,
322 UART_SCCM_TX | UART_SCCM_RX);
323 clrbits32((u32 *) & immap->im_scc[2].scc_gsmrl,
324 SCC_GSMRL_ENR | SCC_GSMRL_ENT);
325#endif
326
327#ifdef CONFIG_SERIAL_CPM_SCC4
328 clrbits32((u32 *) & immap->im_scc[3].scc_sccm,
329 UART_SCCM_TX | UART_SCCM_RX);
330 clrbits32((u32 *) & immap->im_scc[3].scc_gsmrl,
331 SCC_GSMRL_ENR | SCC_GSMRL_ENT);
332#endif
333
334 iounmap(bcsr);
335 iounmap(immap);
336}
337
338#ifdef CONFIG_PCI
339static void m82xx_pci_mask_irq(unsigned int irq)
340{
341 int bit = irq - pci_int_base;
342
343 *pci_regs.pci_int_mask_reg |= (1 << (31 - bit));
344 return;
345}
346
347static void m82xx_pci_unmask_irq(unsigned int irq)
348{
349 int bit = irq - pci_int_base;
350
351 *pci_regs.pci_int_mask_reg &= ~(1 << (31 - bit));
352 return;
353}
354
355static void m82xx_pci_mask_and_ack(unsigned int irq)
356{
357 int bit = irq - pci_int_base;
358
359 *pci_regs.pci_int_mask_reg |= (1 << (31 - bit));
360 return;
361}
362
363static void m82xx_pci_end_irq(unsigned int irq)
364{
365 int bit = irq - pci_int_base;
366
367 *pci_regs.pci_int_mask_reg &= ~(1 << (31 - bit));
368 return;
369}
370
371struct hw_interrupt_type m82xx_pci_ic = {
372 .typename = "MPC82xx ADS PCI",
373 .name = "MPC82xx ADS PCI",
374 .enable = m82xx_pci_unmask_irq,
375 .disable = m82xx_pci_mask_irq,
376 .ack = m82xx_pci_mask_and_ack,
377 .end = m82xx_pci_end_irq,
378 .mask = m82xx_pci_mask_irq,
379 .mask_ack = m82xx_pci_mask_and_ack,
380 .unmask = m82xx_pci_unmask_irq,
381 .eoi = m82xx_pci_end_irq,
382};
383
384static void
385m82xx_pci_irq_demux(unsigned int irq, struct irq_desc *desc)
386{
387 unsigned long stat, mask, pend;
388 int bit;
389
390 for (;;) {
391 stat = *pci_regs.pci_int_stat_reg;
392 mask = *pci_regs.pci_int_mask_reg;
393 pend = stat & ~mask & 0xf0000000;
394 if (!pend)
395 break;
396 for (bit = 0; pend != 0; ++bit, pend <<= 1) {
397 if (pend & 0x80000000)
398 __do_IRQ(pci_int_base + bit);
399 }
400 }
401}
402
403static int pci_pic_host_match(struct irq_host *h, struct device_node *node)
404{
405 return node == pci_pic_node;
406}
407
408static int pci_pic_host_map(struct irq_host *h, unsigned int virq,
409 irq_hw_number_t hw)
410{
411 get_irq_desc(virq)->status |= IRQ_LEVEL;
412 set_irq_chip(virq, &m82xx_pci_ic);
413 return 0;
414}
415
416static void pci_host_unmap(struct irq_host *h, unsigned int virq)
417{
418 /* remove chip and handler */
419 set_irq_chip(virq, NULL);
420}
421
422static struct irq_host_ops pci_pic_host_ops = {
423 .match = pci_pic_host_match,
424 .map = pci_pic_host_map,
425 .unmap = pci_host_unmap,
426};
427
428void m82xx_pci_init_irq(void)
429{
430 int irq;
431 cpm2_map_t *immap;
432 struct device_node *np;
433 struct resource r;
434 const u32 *regs;
435 unsigned int size;
436 const u32 *irq_map;
437 int i;
438 unsigned int irq_max, irq_min;
439
440 if ((np = of_find_node_by_type(NULL, "soc")) == NULL) {
441 printk(KERN_INFO "No SOC node in device tree\n");
442 return;
443 }
444 memset(&r, 0, sizeof(r));
445 if (of_address_to_resource(np, 0, &r)) {
446 printk(KERN_INFO "No SOC reg property in device tree\n");
447 return;
448 }
449 immap = ioremap(r.start, sizeof(*immap));
450 of_node_put(np);
451
452 /* install the demultiplexer for the PCI cascade interrupt */
453 np = of_find_node_by_type(NULL, "pci");
454 if (!np) {
455 printk(KERN_INFO "No pci node on device tree\n");
456 iounmap(immap);
457 return;
458 }
459 irq_map = of_get_property(np, "interrupt-map", &size);
460 if ((!irq_map) || (size <= 7)) {
461 printk(KERN_INFO "No interrupt-map property of pci node\n");
462 iounmap(immap);
463 return;
464 }
465 size /= sizeof(irq_map[0]);
466 for (i = 0, irq_max = 0, irq_min = 512; i < size; i += 7, irq_map += 7) {
467 if (irq_map[5] < irq_min)
468 irq_min = irq_map[5];
469 if (irq_map[5] > irq_max)
470 irq_max = irq_map[5];
471 }
472 pci_int_base = irq_min;
473 irq = irq_of_parse_and_map(np, 0);
474 set_irq_chained_handler(irq, m82xx_pci_irq_demux);
475 of_node_put(np);
476 np = of_find_node_by_type(NULL, "pci-pic");
477 if (!np) {
478 printk(KERN_INFO "No pci pic node on device tree\n");
479 iounmap(immap);
480 return;
481 }
482 pci_pic_node = of_node_get(np);
483 /* PCI interrupt controller registers: status and mask */
484 regs = of_get_property(np, "reg", &size);
485 if ((!regs) || (size <= 2)) {
486 printk(KERN_INFO "No reg property in pci pic node\n");
487 iounmap(immap);
488 return;
489 }
490 pci_regs.pci_int_stat_reg =
491 ioremap(regs[0], sizeof(*pci_regs.pci_int_stat_reg));
492 pci_regs.pci_int_mask_reg =
493 ioremap(regs[1], sizeof(*pci_regs.pci_int_mask_reg));
494 of_node_put(np);
495 /* configure chip select for PCI interrupt controller */
496 immap->im_memctl.memc_br3 = regs[0] | 0x00001801;
497 immap->im_memctl.memc_or3 = 0xffff8010;
498 /* make PCI IRQ level sensitive */
499 immap->im_intctl.ic_siexr &= ~(1 << (14 - (irq - SIU_INT_IRQ1)));
500
501 /* mask all PCI interrupts */
502 *pci_regs.pci_int_mask_reg |= 0xfff00000;
503 iounmap(immap);
504 pci_pic_host =
505 irq_alloc_host(IRQ_HOST_MAP_LINEAR, irq_max - irq_min + 1,
506 &pci_pic_host_ops, irq_max + 1);
507 return;
508}
509
510static int m82xx_pci_exclude_device(struct pci_controller *hose,
511 u_char bus, u_char devfn)
512{
513 if (bus == 0 && PCI_SLOT(devfn) == 0)
514 return PCIBIOS_DEVICE_NOT_FOUND;
515 else
516 return PCIBIOS_SUCCESSFUL;
517}
518
519static void __init mpc82xx_add_bridge(struct device_node *np)
520{
521 int len;
522 struct pci_controller *hose;
523 struct resource r;
524 const int *bus_range;
525 const uint *ptr;
526
527 memset(&r, 0, sizeof(r));
528 if (of_address_to_resource(np, 0, &r)) {
529 printk(KERN_INFO "No PCI reg property in device tree\n");
530 return;
531 }
532 if (!(ptr = of_get_property(np, "clock-frequency", NULL))) {
533 printk(KERN_INFO "No clock-frequency property in PCI node");
534 return;
535 }
536 pci_clk_frq = *ptr;
537 of_node_put(np);
538 bus_range = of_get_property(np, "bus-range", &len);
539 if (bus_range == NULL || len < 2 * sizeof(int)) {
540 printk(KERN_WARNING "Can't get bus-range for %s, assume"
541 " bus 0\n", np->full_name);
542 }
543
544 pci_assign_all_buses = 1;
545
546 hose = pcibios_alloc_controller(np);
547
548 if (!hose)
549 return;
550
551 hose->first_busno = bus_range ? bus_range[0] : 0;
552 hose->last_busno = bus_range ? bus_range[1] : 0xff;
553
554 setup_indirect_pci(hose,
555 r.start + offsetof(pci_cpm2_t, pci_cfg_addr),
556 r.start + offsetof(pci_cpm2_t, pci_cfg_data),
557 0);
558
559 pci_process_bridge_OF_ranges(hose, np, 1);
560}
561#endif
562
563/*
564 * Setup the architecture
565 */
566static void __init mpc82xx_ads_setup_arch(void)
567{
568#ifdef CONFIG_PCI
569 struct device_node *np;
570#endif
571
572 if (ppc_md.progress)
573 ppc_md.progress("mpc82xx_ads_setup_arch()", 0);
574 cpm2_reset();
575
576 /* Map I/O region to a 256MB BAT */
577
578 m82xx_board_setup();
579
580#ifdef CONFIG_PCI
581 ppc_md.pci_exclude_device = m82xx_pci_exclude_device;
582 for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
583 mpc82xx_add_bridge(np);
584
585 of_node_put(np);
586#endif
587
588#ifdef CONFIG_ROOT_NFS
589 ROOT_DEV = Root_NFS;
590#else
591 ROOT_DEV = Root_HDA1;
592#endif
593
594 if (ppc_md.progress)
595 ppc_md.progress("mpc82xx_ads_setup_arch(), finish", 0);
596}
597
598/*
599 * Called very early, device-tree isn't unflattened
600 */
601static int __init mpc82xx_ads_probe(void)
602{
603 /* We always match for now, eventually we should look at
604 * the flat dev tree to ensure this is the board we are
605 * supposed to run on
606 */
607 return 1;
608}
609
610#define RMR_CSRE 0x00000001
611static void m82xx_restart(char *cmd)
612{
613 __volatile__ unsigned char dummy;
614
615 local_irq_disable();
616 ((cpm2_map_t *) cpm2_immr)->im_clkrst.car_rmr |= RMR_CSRE;
617
618 /* Clear the ME,EE,IR & DR bits in MSR to cause checkstop */
619 mtmsr(mfmsr() & ~(MSR_ME | MSR_EE | MSR_IR | MSR_DR));
620 dummy = ((cpm2_map_t *) cpm2_immr)->im_clkrst.res[0];
621 printk("Restart failed\n");
622 while (1) ;
623}
624
625static void m82xx_halt(void)
626{
627 local_irq_disable();
628 while (1) ;
629}
630
631define_machine(mpc82xx_ads)
632{
633 .name = "MPC82xx ADS",
634 .probe = mpc82xx_ads_probe,
635 .setup_arch = mpc82xx_ads_setup_arch,
636 .init_IRQ = mpc82xx_ads_pic_init,
637 .show_cpuinfo = mpc82xx_ads_show_cpuinfo,
638 .get_irq = cpm2_get_irq,
639 .calibrate_decr = m82xx_calibrate_decr,
640 .restart = m82xx_restart,.halt = m82xx_halt,
641};
diff --git a/arch/powerpc/platforms/82xx/pq2.c b/arch/powerpc/platforms/82xx/pq2.c
new file mode 100644
index 000000000000..a497cbaa1ac5
--- /dev/null
+++ b/arch/powerpc/platforms/82xx/pq2.c
@@ -0,0 +1,82 @@
1/*
2 * Common PowerQUICC II code.
3 *
4 * Author: Scott Wood <scottwood@freescale.com>
5 * Copyright (c) 2007 Freescale Semiconductor
6 *
7 * Based on code by Vitaly Bordug <vbordug@ru.mvista.com>
8 * pq2_restart fix by Wade Farnsworth <wfarnsworth@mvista.com>
9 * Copyright (c) 2006 MontaVista Software, Inc.
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 <asm/cpm2.h>
18#include <asm/io.h>
19#include <asm/pci-bridge.h>
20#include <asm/system.h>
21
22#include <platforms/82xx/pq2.h>
23
24#define RMR_CSRE 0x00000001
25
26void pq2_restart(char *cmd)
27{
28 local_irq_disable();
29 setbits32(&cpm2_immr->im_clkrst.car_rmr, RMR_CSRE);
30
31 /* Clear the ME,EE,IR & DR bits in MSR to cause checkstop */
32 mtmsr(mfmsr() & ~(MSR_ME | MSR_EE | MSR_IR | MSR_DR));
33 in_8(&cpm2_immr->im_clkrst.res[0]);
34
35 panic("Restart failed\n");
36}
37
38#ifdef CONFIG_PCI
39static int pq2_pci_exclude_device(struct pci_controller *hose,
40 u_char bus, u8 devfn)
41{
42 if (bus == 0 && PCI_SLOT(devfn) == 0)
43 return PCIBIOS_DEVICE_NOT_FOUND;
44 else
45 return PCIBIOS_SUCCESSFUL;
46}
47
48static void __init pq2_pci_add_bridge(struct device_node *np)
49{
50 struct pci_controller *hose;
51 struct resource r;
52
53 if (of_address_to_resource(np, 0, &r) || r.end - r.start < 0x10b)
54 goto err;
55
56 pci_assign_all_buses = 1;
57
58 hose = pcibios_alloc_controller(np);
59 if (!hose)
60 return;
61
62 hose->arch_data = np;
63
64 setup_indirect_pci(hose, r.start + 0x100, r.start + 0x104, 0);
65 pci_process_bridge_OF_ranges(hose, np, 1);
66
67 return;
68
69err:
70 printk(KERN_ERR "No valid PCI reg property in device tree\n");
71}
72
73void __init pq2_init_pci(void)
74{
75 struct device_node *np = NULL;
76
77 ppc_md.pci_exclude_device = pq2_pci_exclude_device;
78
79 while ((np = of_find_compatible_node(np, NULL, "fsl,pq2-pci")))
80 pq2_pci_add_bridge(np);
81}
82#endif
diff --git a/arch/powerpc/platforms/82xx/pq2.h b/arch/powerpc/platforms/82xx/pq2.h
new file mode 100644
index 000000000000..a41f84ae2325
--- /dev/null
+++ b/arch/powerpc/platforms/82xx/pq2.h
@@ -0,0 +1,20 @@
1#ifndef _PQ2_H
2#define _PQ2_H
3
4void pq2_restart(char *cmd);
5
6#ifdef CONFIG_PCI
7int pq2ads_pci_init_irq(void);
8void pq2_init_pci(void);
9#else
10static inline int pq2ads_pci_init_irq(void)
11{
12 return 0;
13}
14
15static inline void pq2_init_pci(void)
16{
17}
18#endif
19
20#endif
diff --git a/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c b/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c
new file mode 100644
index 000000000000..a8013816125c
--- /dev/null
+++ b/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c
@@ -0,0 +1,195 @@
1/*
2 * PQ2 ADS-style PCI interrupt controller
3 *
4 * Copyright 2007 Freescale Semiconductor, Inc.
5 * Author: Scott Wood <scottwood@freescale.com>
6 *
7 * Loosely based on mpc82xx ADS support by Vitaly Bordug <vbordug@ru.mvista.com>
8 * Copyright (c) 2006 MontaVista Software, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License version 2 as published
12 * by the Free Software Foundation.
13 */
14
15#include <linux/init.h>
16#include <linux/spinlock.h>
17#include <linux/irq.h>
18#include <linux/types.h>
19#include <linux/bootmem.h>
20
21#include <asm/io.h>
22#include <asm/prom.h>
23#include <asm/cpm2.h>
24
25#include "pq2.h"
26
27static DEFINE_SPINLOCK(pci_pic_lock);
28
29struct pq2ads_pci_pic {
30 struct device_node *node;
31 struct irq_host *host;
32
33 struct {
34 u32 stat;
35 u32 mask;
36 } __iomem *regs;
37};
38
39#define NUM_IRQS 32
40
41static void pq2ads_pci_mask_irq(unsigned int virq)
42{
43 struct pq2ads_pci_pic *priv = get_irq_chip_data(virq);
44 int irq = NUM_IRQS - virq_to_hw(virq) - 1;
45
46 if (irq != -1) {
47 unsigned long flags;
48 spin_lock_irqsave(&pci_pic_lock, flags);
49
50 setbits32(&priv->regs->mask, 1 << irq);
51 mb();
52
53 spin_unlock_irqrestore(&pci_pic_lock, flags);
54 }
55}
56
57static void pq2ads_pci_unmask_irq(unsigned int virq)
58{
59 struct pq2ads_pci_pic *priv = get_irq_chip_data(virq);
60 int irq = NUM_IRQS - virq_to_hw(virq) - 1;
61
62 if (irq != -1) {
63 unsigned long flags;
64
65 spin_lock_irqsave(&pci_pic_lock, flags);
66 clrbits32(&priv->regs->mask, 1 << irq);
67 spin_unlock_irqrestore(&pci_pic_lock, flags);
68 }
69}
70
71static struct irq_chip pq2ads_pci_ic = {
72 .typename = "PQ2 ADS PCI",
73 .name = "PQ2 ADS PCI",
74 .end = pq2ads_pci_unmask_irq,
75 .mask = pq2ads_pci_mask_irq,
76 .mask_ack = pq2ads_pci_mask_irq,
77 .ack = pq2ads_pci_mask_irq,
78 .unmask = pq2ads_pci_unmask_irq,
79 .enable = pq2ads_pci_unmask_irq,
80 .disable = pq2ads_pci_mask_irq
81};
82
83static void pq2ads_pci_irq_demux(unsigned int irq, struct irq_desc *desc)
84{
85 struct pq2ads_pci_pic *priv = desc->handler_data;
86 u32 stat, mask, pend;
87 int bit;
88
89 for (;;) {
90 stat = in_be32(&priv->regs->stat);
91 mask = in_be32(&priv->regs->mask);
92
93 pend = stat & ~mask;
94
95 if (!pend)
96 break;
97
98 for (bit = 0; pend != 0; ++bit, pend <<= 1) {
99 if (pend & 0x80000000) {
100 int virq = irq_linear_revmap(priv->host, bit);
101 generic_handle_irq(virq);
102 }
103 }
104 }
105}
106
107static int pci_pic_host_map(struct irq_host *h, unsigned int virq,
108 irq_hw_number_t hw)
109{
110 get_irq_desc(virq)->status |= IRQ_LEVEL;
111 set_irq_chip_data(virq, h->host_data);
112 set_irq_chip(virq, &pq2ads_pci_ic);
113 return 0;
114}
115
116static void pci_host_unmap(struct irq_host *h, unsigned int virq)
117{
118 /* remove chip and handler */
119 set_irq_chip_data(virq, NULL);
120 set_irq_chip(virq, NULL);
121}
122
123static struct irq_host_ops pci_pic_host_ops = {
124 .map = pci_pic_host_map,
125 .unmap = pci_host_unmap,
126};
127
128int __init pq2ads_pci_init_irq(void)
129{
130 struct pq2ads_pci_pic *priv;
131 struct irq_host *host;
132 struct device_node *np;
133 int ret = -ENODEV;
134 int irq;
135
136 np = of_find_compatible_node(NULL, NULL, "fsl,pq2ads-pci-pic");
137 if (!np) {
138 printk(KERN_ERR "No pci pic node in device tree.\n");
139 of_node_put(np);
140 goto out;
141 }
142
143 irq = irq_of_parse_and_map(np, 0);
144 if (irq == NO_IRQ) {
145 printk(KERN_ERR "No interrupt in pci pic node.\n");
146 of_node_put(np);
147 goto out;
148 }
149
150 priv = alloc_bootmem(sizeof(struct pq2ads_pci_pic));
151 if (!priv) {
152 of_node_put(np);
153 ret = -ENOMEM;
154 goto out_unmap_irq;
155 }
156
157 /* PCI interrupt controller registers: status and mask */
158 priv->regs = of_iomap(np, 0);
159 if (!priv->regs) {
160 printk(KERN_ERR "Cannot map PCI PIC registers.\n");
161 goto out_free_bootmem;
162 }
163
164 /* mask all PCI interrupts */
165 out_be32(&priv->regs->mask, ~0);
166 mb();
167
168 host = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, NUM_IRQS,
169 &pci_pic_host_ops, NUM_IRQS);
170 if (!host) {
171 ret = -ENOMEM;
172 goto out_unmap_regs;
173 }
174
175 host->host_data = priv;
176
177 priv->host = host;
178 host->host_data = priv;
179 set_irq_data(irq, priv);
180 set_irq_chained_handler(irq, pq2ads_pci_irq_demux);
181
182 of_node_put(np);
183 return 0;
184
185out_unmap_regs:
186 iounmap(priv->regs);
187out_free_bootmem:
188 free_bootmem((unsigned long)priv,
189 sizeof(sizeof(struct pq2ads_pci_pic)));
190 of_node_put(np);
191out_unmap_irq:
192 irq_dispose_mapping(irq);
193out:
194 return ret;
195}
diff --git a/arch/powerpc/platforms/82xx/pq2ads.h b/arch/powerpc/platforms/82xx/pq2ads.h
index 5b5cca6c8c88..984db42cc8e7 100644
--- a/arch/powerpc/platforms/82xx/pq2ads.h
+++ b/arch/powerpc/platforms/82xx/pq2ads.h
@@ -23,11 +23,6 @@
23#define __MACH_ADS8260_DEFS 23#define __MACH_ADS8260_DEFS
24 24
25#include <linux/seq_file.h> 25#include <linux/seq_file.h>
26#include <asm/ppcboot.h>
27
28/* For our show_cpuinfo hooks. */
29#define CPUINFO_VENDOR "Freescale Semiconductor"
30#define CPUINFO_MACHINE "PQ2 ADS PowerPC"
31 26
32/* Backword-compatibility stuff for the drivers */ 27/* Backword-compatibility stuff for the drivers */
33#define CPM_MAP_ADDR ((uint)0xf0000000) 28#define CPM_MAP_ADDR ((uint)0xf0000000)
@@ -58,9 +53,5 @@
58#define SIU_INT_SCC3 ((uint)0x2a+CPM_IRQ_OFFSET) 53#define SIU_INT_SCC3 ((uint)0x2a+CPM_IRQ_OFFSET)
59#define SIU_INT_SCC4 ((uint)0x2b+CPM_IRQ_OFFSET) 54#define SIU_INT_SCC4 ((uint)0x2b+CPM_IRQ_OFFSET)
60 55
61void m82xx_pci_init_irq(void);
62void mpc82xx_ads_show_cpuinfo(struct seq_file*);
63void m82xx_calibrate_decr(void);
64
65#endif /* __MACH_ADS8260_DEFS */ 56#endif /* __MACH_ADS8260_DEFS */
66#endif /* __KERNEL__ */ 57#endif /* __KERNEL__ */
diff --git a/arch/powerpc/platforms/82xx/pq2fads.c b/arch/powerpc/platforms/82xx/pq2fads.c
new file mode 100644
index 000000000000..4f457a9c79ae
--- /dev/null
+++ b/arch/powerpc/platforms/82xx/pq2fads.c
@@ -0,0 +1,198 @@
1/*
2 * PQ2FADS board support
3 *
4 * Copyright 2007 Freescale Semiconductor, Inc.
5 * Author: Scott Wood <scottwood@freescale.com>
6 *
7 * Loosely based on mp82xx ADS support by Vitaly Bordug <vbordug@ru.mvista.com>
8 * Copyright (c) 2006 MontaVista Software, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License version 2 as published
12 * by the Free Software Foundation.
13 */
14
15#include <linux/init.h>
16#include <linux/interrupt.h>
17#include <linux/fsl_devices.h>
18
19#include <asm/io.h>
20#include <asm/cpm2.h>
21#include <asm/udbg.h>
22#include <asm/machdep.h>
23#include <asm/of_platform.h>
24#include <asm/time.h>
25
26#include <sysdev/fsl_soc.h>
27#include <sysdev/cpm2_pic.h>
28
29#include "pq2ads.h"
30#include "pq2.h"
31
32static void __init pq2fads_pic_init(void)
33{
34 struct device_node *np = of_find_compatible_node(NULL, NULL, "fsl,cpm2-pic");
35 if (!np) {
36 printk(KERN_ERR "PIC init: can not find fsl,cpm2-pic node\n");
37 return;
38 }
39
40 cpm2_pic_init(np);
41 of_node_put(np);
42
43 /* Initialize stuff for the 82xx CPLD IC and install demux */
44 pq2ads_pci_init_irq();
45}
46
47struct cpm_pin {
48 int port, pin, flags;
49};
50
51static struct cpm_pin pq2fads_pins[] = {
52 /* SCC1 */
53 {3, 30, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY},
54 {3, 31, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
55
56 /* SCC2 */
57 {3, 27, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
58 {3, 28, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
59
60 /* FCC2 */
61 {1, 18, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
62 {1, 19, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
63 {1, 20, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
64 {1, 21, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
65 {1, 22, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
66 {1, 23, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
67 {1, 24, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
68 {1, 25, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
69 {1, 26, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
70 {1, 27, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
71 {1, 28, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
72 {1, 29, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY},
73 {1, 30, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
74 {1, 31, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
75 {2, 18, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
76 {2, 19, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
77
78 /* FCC3 */
79 {1, 4, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
80 {1, 5, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
81 {1, 6, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
82 {1, 7, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
83 {1, 8, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
84 {1, 9, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
85 {1, 10, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
86 {1, 11, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
87 {1, 12, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
88 {1, 13, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
89 {1, 14, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
90 {1, 15, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
91 {1, 16, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
92 {1, 17, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
93 {2, 16, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
94 {2, 17, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
95};
96
97static void __init init_ioports(void)
98{
99 int i;
100
101 for (i = 0; i < ARRAY_SIZE(pq2fads_pins); i++) {
102 struct cpm_pin *pin = &pq2fads_pins[i];
103 cpm2_set_pin(pin->port, pin->pin, pin->flags);
104 }
105
106 cpm2_clk_setup(CPM_CLK_SCC1, CPM_BRG1, CPM_CLK_RX);
107 cpm2_clk_setup(CPM_CLK_SCC1, CPM_BRG1, CPM_CLK_TX);
108 cpm2_clk_setup(CPM_CLK_SCC2, CPM_BRG2, CPM_CLK_RX);
109 cpm2_clk_setup(CPM_CLK_SCC2, CPM_BRG2, CPM_CLK_TX);
110 cpm2_clk_setup(CPM_CLK_FCC2, CPM_CLK13, CPM_CLK_RX);
111 cpm2_clk_setup(CPM_CLK_FCC2, CPM_CLK14, CPM_CLK_TX);
112 cpm2_clk_setup(CPM_CLK_FCC3, CPM_CLK15, CPM_CLK_RX);
113 cpm2_clk_setup(CPM_CLK_FCC3, CPM_CLK16, CPM_CLK_TX);
114}
115
116static void __init pq2fads_setup_arch(void)
117{
118 struct device_node *np;
119 __be32 __iomem *bcsr;
120
121 if (ppc_md.progress)
122 ppc_md.progress("pq2fads_setup_arch()", 0);
123
124 cpm2_reset();
125
126 np = of_find_compatible_node(NULL, NULL, "fsl,pq2fads-bcsr");
127 if (!np) {
128 printk(KERN_ERR "No fsl,pq2fads-bcsr in device tree\n");
129 return;
130 }
131
132 bcsr = of_iomap(np, 0);
133 if (!bcsr) {
134 printk(KERN_ERR "Cannot map BCSR registers\n");
135 return;
136 }
137
138 of_node_put(np);
139
140 /* Enable the serial and ethernet ports */
141
142 clrbits32(&bcsr[1], BCSR1_RS232_EN1 | BCSR1_RS232_EN2 | BCSR1_FETHIEN);
143 setbits32(&bcsr[1], BCSR1_FETH_RST);
144
145 clrbits32(&bcsr[3], BCSR3_FETHIEN2);
146 setbits32(&bcsr[3], BCSR3_FETH2_RST);
147
148 iounmap(bcsr);
149
150 init_ioports();
151
152 /* Enable external IRQs */
153 clrbits32(&cpm2_immr->im_siu_conf.siu_82xx.sc_siumcr, 0x0c000000);
154
155 pq2_init_pci();
156
157 if (ppc_md.progress)
158 ppc_md.progress("pq2fads_setup_arch(), finish", 0);
159}
160
161/*
162 * Called very early, device-tree isn't unflattened
163 */
164static int __init pq2fads_probe(void)
165{
166 unsigned long root = of_get_flat_dt_root();
167 return of_flat_dt_is_compatible(root, "fsl,pq2fads");
168}
169
170static struct of_device_id __initdata of_bus_ids[] = {
171 { .name = "soc", },
172 { .name = "cpm", },
173 { .name = "localbus", },
174 {},
175};
176
177static int __init declare_of_platform_devices(void)
178{
179 if (!machine_is(pq2fads))
180 return 0;
181
182 /* Publish the QE devices */
183 of_platform_bus_probe(NULL, of_bus_ids, NULL);
184 return 0;
185}
186device_initcall(declare_of_platform_devices);
187
188define_machine(pq2fads)
189{
190 .name = "Freescale PQ2FADS",
191 .probe = pq2fads_probe,
192 .setup_arch = pq2fads_setup_arch,
193 .init_IRQ = pq2fads_pic_init,
194 .get_irq = cpm2_get_irq,
195 .calibrate_decr = generic_calibrate_decr,
196 .restart = pq2_restart,
197 .progress = udbg_progress,
198};