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