diff options
Diffstat (limited to 'arch/powerpc/platforms/85xx')
-rw-r--r-- | arch/powerpc/platforms/85xx/Kconfig | 9 | ||||
-rw-r--r-- | arch/powerpc/platforms/85xx/Makefile | 1 | ||||
-rw-r--r-- | arch/powerpc/platforms/85xx/mpc85xx_cds.c | 359 | ||||
-rw-r--r-- | arch/powerpc/platforms/85xx/mpc85xx_cds.h | 43 |
4 files changed, 411 insertions, 1 deletions
diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms/85xx/Kconfig index 06e371282f57..454fc53289ab 100644 --- a/arch/powerpc/platforms/85xx/Kconfig +++ b/arch/powerpc/platforms/85xx/Kconfig | |||
@@ -11,13 +11,20 @@ config MPC8540_ADS | |||
11 | help | 11 | help |
12 | This option enables support for the MPC 8540 ADS board | 12 | This option enables support for the MPC 8540 ADS board |
13 | 13 | ||
14 | config MPC85xx_CDS | ||
15 | bool "Freescale MPC85xx CDS" | ||
16 | select DEFAULT_UIMAGE | ||
17 | select PPC_I8259 if PCI | ||
18 | help | ||
19 | This option enables support for the MPC85xx CDS board | ||
20 | |||
14 | endchoice | 21 | endchoice |
15 | 22 | ||
16 | config MPC8540 | 23 | config MPC8540 |
17 | bool | 24 | bool |
18 | select PPC_UDBG_16550 | 25 | select PPC_UDBG_16550 |
19 | select PPC_INDIRECT_PCI | 26 | select PPC_INDIRECT_PCI |
20 | default y if MPC8540_ADS | 27 | default y if MPC8540_ADS || MPC85xx_CDS |
21 | 28 | ||
22 | config PPC_INDIRECT_PCI_BE | 29 | config PPC_INDIRECT_PCI_BE |
23 | bool | 30 | bool |
diff --git a/arch/powerpc/platforms/85xx/Makefile b/arch/powerpc/platforms/85xx/Makefile index ffc4139cb214..7615aa59c78b 100644 --- a/arch/powerpc/platforms/85xx/Makefile +++ b/arch/powerpc/platforms/85xx/Makefile | |||
@@ -3,3 +3,4 @@ | |||
3 | # | 3 | # |
4 | obj-$(CONFIG_PPC_85xx) += misc.o pci.o | 4 | obj-$(CONFIG_PPC_85xx) += misc.o pci.o |
5 | obj-$(CONFIG_MPC8540_ADS) += mpc85xx_ads.o | 5 | obj-$(CONFIG_MPC8540_ADS) += mpc85xx_ads.o |
6 | obj-$(CONFIG_MPC85xx_CDS) += mpc85xx_cds.o | ||
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_cds.c b/arch/powerpc/platforms/85xx/mpc85xx_cds.c new file mode 100644 index 000000000000..18e6e11f7020 --- /dev/null +++ b/arch/powerpc/platforms/85xx/mpc85xx_cds.c | |||
@@ -0,0 +1,359 @@ | |||
1 | /* | ||
2 | * MPC85xx setup and early boot code plus other random bits. | ||
3 | * | ||
4 | * Maintained by Kumar Gala (see MAINTAINERS for contact information) | ||
5 | * | ||
6 | * Copyright 2005 Freescale Semiconductor 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/config.h> | ||
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/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 | |||
31 | #include <asm/system.h> | ||
32 | #include <asm/pgtable.h> | ||
33 | #include <asm/page.h> | ||
34 | #include <asm/atomic.h> | ||
35 | #include <asm/time.h> | ||
36 | #include <asm/io.h> | ||
37 | #include <asm/machdep.h> | ||
38 | #include <asm/ipic.h> | ||
39 | #include <asm/bootinfo.h> | ||
40 | #include <asm/pci-bridge.h> | ||
41 | #include <asm/mpc85xx.h> | ||
42 | #include <asm/irq.h> | ||
43 | #include <mm/mmu_decl.h> | ||
44 | #include <asm/prom.h> | ||
45 | #include <asm/udbg.h> | ||
46 | #include <asm/mpic.h> | ||
47 | #include <asm/i8259.h> | ||
48 | |||
49 | #include <sysdev/fsl_soc.h> | ||
50 | #include "mpc85xx.h" | ||
51 | |||
52 | #ifndef CONFIG_PCI | ||
53 | unsigned long isa_io_base = 0; | ||
54 | unsigned long isa_mem_base = 0; | ||
55 | #endif | ||
56 | |||
57 | static int cds_pci_slot = 2; | ||
58 | static volatile u8 *cadmus; | ||
59 | |||
60 | /* | ||
61 | * Internal interrupts are all Level Sensitive, and Positive Polarity | ||
62 | * | ||
63 | * Note: Likely, this table and the following function should be | ||
64 | * obtained and derived from the OF Device Tree. | ||
65 | */ | ||
66 | static u_char mpc85xx_cds_openpic_initsenses[] __initdata = { | ||
67 | MPC85XX_INTERNAL_IRQ_SENSES, | ||
68 | #if defined(CONFIG_PCI) | ||
69 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Ext 0: PCI slot 0 */ | ||
70 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* Ext 1: PCI slot 1 */ | ||
71 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* Ext 2: PCI slot 2 */ | ||
72 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* Ext 3: PCI slot 3 */ | ||
73 | #else | ||
74 | 0x0, /* External 0: */ | ||
75 | 0x0, /* External 1: */ | ||
76 | 0x0, /* External 2: */ | ||
77 | 0x0, /* External 3: */ | ||
78 | #endif | ||
79 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* External 5: PHY */ | ||
80 | 0x0, /* External 6: */ | ||
81 | 0x0, /* External 7: */ | ||
82 | 0x0, /* External 8: */ | ||
83 | 0x0, /* External 9: */ | ||
84 | 0x0, /* External 10: */ | ||
85 | #ifdef CONFIG_PCI | ||
86 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* Ext 11: PCI2 slot 0 */ | ||
87 | #else | ||
88 | 0x0, /* External 11: */ | ||
89 | #endif | ||
90 | }; | ||
91 | |||
92 | |||
93 | #ifdef CONFIG_PCI | ||
94 | /* | ||
95 | * interrupt routing | ||
96 | */ | ||
97 | int | ||
98 | mpc85xx_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) | ||
99 | { | ||
100 | struct pci_controller *hose = pci_bus_to_hose(dev->bus->number); | ||
101 | |||
102 | if (!hose->index) | ||
103 | { | ||
104 | /* Handle PCI1 interrupts */ | ||
105 | char pci_irq_table[][4] = | ||
106 | /* | ||
107 | * PCI IDSEL/INTPIN->INTLINE | ||
108 | * A B C D | ||
109 | */ | ||
110 | |||
111 | /* Note IRQ assignment for slots is based on which slot the elysium is | ||
112 | * in -- in this setup elysium is in slot #2 (this PIRQA as first | ||
113 | * interrupt on slot */ | ||
114 | { | ||
115 | { 0, 1, 2, 3 }, /* 16 - PMC */ | ||
116 | { 0, 1, 2, 3 }, /* 17 P2P (Tsi320) */ | ||
117 | { 0, 1, 2, 3 }, /* 18 - Slot 1 */ | ||
118 | { 1, 2, 3, 0 }, /* 19 - Slot 2 */ | ||
119 | { 2, 3, 0, 1 }, /* 20 - Slot 3 */ | ||
120 | { 3, 0, 1, 2 }, /* 21 - Slot 4 */ | ||
121 | }; | ||
122 | |||
123 | const long min_idsel = 16, max_idsel = 21, irqs_per_slot = 4; | ||
124 | int i, j; | ||
125 | |||
126 | for (i = 0; i < 6; i++) | ||
127 | for (j = 0; j < 4; j++) | ||
128 | pci_irq_table[i][j] = | ||
129 | ((pci_irq_table[i][j] + 5 - | ||
130 | cds_pci_slot) & 0x3) + PIRQ0A; | ||
131 | |||
132 | return PCI_IRQ_TABLE_LOOKUP; | ||
133 | } else { | ||
134 | /* Handle PCI2 interrupts (if we have one) */ | ||
135 | char pci_irq_table[][4] = | ||
136 | { | ||
137 | /* | ||
138 | * We only have one slot and one interrupt | ||
139 | * going to PIRQA - PIRQD */ | ||
140 | { PIRQ1A, PIRQ1A, PIRQ1A, PIRQ1A }, /* 21 - slot 0 */ | ||
141 | }; | ||
142 | |||
143 | const long min_idsel = 21, max_idsel = 21, irqs_per_slot = 4; | ||
144 | |||
145 | return PCI_IRQ_TABLE_LOOKUP; | ||
146 | } | ||
147 | } | ||
148 | |||
149 | #define ARCADIA_HOST_BRIDGE_IDSEL 17 | ||
150 | #define ARCADIA_2ND_BRIDGE_IDSEL 3 | ||
151 | |||
152 | extern int mpc85xx_pci2_busno; | ||
153 | |||
154 | int | ||
155 | mpc85xx_exclude_device(u_char bus, u_char devfn) | ||
156 | { | ||
157 | if (bus == 0 && PCI_SLOT(devfn) == 0) | ||
158 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
159 | if (mpc85xx_pci2_busno) | ||
160 | if (bus == (mpc85xx_pci2_busno) && PCI_SLOT(devfn) == 0) | ||
161 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
162 | /* We explicitly do not go past the Tundra 320 Bridge */ | ||
163 | if ((bus == 1) && (PCI_SLOT(devfn) == ARCADIA_2ND_BRIDGE_IDSEL)) | ||
164 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
165 | if ((bus == 0) && (PCI_SLOT(devfn) == ARCADIA_2ND_BRIDGE_IDSEL)) | ||
166 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
167 | else | ||
168 | return PCIBIOS_SUCCESSFUL; | ||
169 | } | ||
170 | |||
171 | void __init | ||
172 | mpc85xx_cds_pcibios_fixup(void) | ||
173 | { | ||
174 | struct pci_dev *dev; | ||
175 | u_char c; | ||
176 | |||
177 | if ((dev = pci_get_device(PCI_VENDOR_ID_VIA, | ||
178 | PCI_DEVICE_ID_VIA_82C586_1, NULL))) { | ||
179 | /* | ||
180 | * U-Boot does not set the enable bits | ||
181 | * for the IDE device. Force them on here. | ||
182 | */ | ||
183 | pci_read_config_byte(dev, 0x40, &c); | ||
184 | c |= 0x03; /* IDE: Chip Enable Bits */ | ||
185 | pci_write_config_byte(dev, 0x40, c); | ||
186 | |||
187 | /* | ||
188 | * Since only primary interface works, force the | ||
189 | * IDE function to standard primary IDE interrupt | ||
190 | * w/ 8259 offset | ||
191 | */ | ||
192 | dev->irq = 14; | ||
193 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); | ||
194 | pci_dev_put(dev); | ||
195 | } | ||
196 | |||
197 | /* | ||
198 | * Force legacy USB interrupt routing | ||
199 | */ | ||
200 | if ((dev = pci_get_device(PCI_VENDOR_ID_VIA, | ||
201 | PCI_DEVICE_ID_VIA_82C586_2, NULL))) { | ||
202 | dev->irq = 10; | ||
203 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 10); | ||
204 | pci_dev_put(dev); | ||
205 | } | ||
206 | |||
207 | if ((dev = pci_get_device(PCI_VENDOR_ID_VIA, | ||
208 | PCI_DEVICE_ID_VIA_82C586_2, dev))) { | ||
209 | dev->irq = 11; | ||
210 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 11); | ||
211 | pci_dev_put(dev); | ||
212 | } | ||
213 | } | ||
214 | #endif /* CONFIG_PCI */ | ||
215 | |||
216 | void __init mpc85xx_cds_pic_init(void) | ||
217 | { | ||
218 | struct mpic *mpic1; | ||
219 | phys_addr_t OpenPIC_PAddr; | ||
220 | |||
221 | /* Determine the Physical Address of the OpenPIC regs */ | ||
222 | OpenPIC_PAddr = get_immrbase() + MPC85xx_OPENPIC_OFFSET; | ||
223 | |||
224 | mpic1 = mpic_alloc(OpenPIC_PAddr, | ||
225 | MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, | ||
226 | 4, MPC85xx_OPENPIC_IRQ_OFFSET, 0, 250, | ||
227 | mpc85xx_cds_openpic_initsenses, | ||
228 | sizeof(mpc85xx_cds_openpic_initsenses), " OpenPIC "); | ||
229 | BUG_ON(mpic1 == NULL); | ||
230 | mpic_assign_isu(mpic1, 0, OpenPIC_PAddr + 0x10200); | ||
231 | mpic_assign_isu(mpic1, 1, OpenPIC_PAddr + 0x10280); | ||
232 | mpic_assign_isu(mpic1, 2, OpenPIC_PAddr + 0x10300); | ||
233 | mpic_assign_isu(mpic1, 3, OpenPIC_PAddr + 0x10380); | ||
234 | mpic_assign_isu(mpic1, 4, OpenPIC_PAddr + 0x10400); | ||
235 | mpic_assign_isu(mpic1, 5, OpenPIC_PAddr + 0x10480); | ||
236 | mpic_assign_isu(mpic1, 6, OpenPIC_PAddr + 0x10500); | ||
237 | mpic_assign_isu(mpic1, 7, OpenPIC_PAddr + 0x10580); | ||
238 | |||
239 | /* dummy mappings to get to 48 */ | ||
240 | mpic_assign_isu(mpic1, 8, OpenPIC_PAddr + 0x10600); | ||
241 | mpic_assign_isu(mpic1, 9, OpenPIC_PAddr + 0x10680); | ||
242 | mpic_assign_isu(mpic1, 10, OpenPIC_PAddr + 0x10700); | ||
243 | mpic_assign_isu(mpic1, 11, OpenPIC_PAddr + 0x10780); | ||
244 | |||
245 | /* External ints */ | ||
246 | mpic_assign_isu(mpic1, 12, OpenPIC_PAddr + 0x10000); | ||
247 | mpic_assign_isu(mpic1, 13, OpenPIC_PAddr + 0x10080); | ||
248 | mpic_assign_isu(mpic1, 14, OpenPIC_PAddr + 0x10100); | ||
249 | |||
250 | mpic_init(mpic1); | ||
251 | |||
252 | #ifdef CONFIG_PCI | ||
253 | mpic_setup_cascade(PIRQ0A, i8259_irq_cascade, NULL); | ||
254 | |||
255 | i8259_init(0,0); | ||
256 | #endif | ||
257 | } | ||
258 | |||
259 | |||
260 | /* | ||
261 | * Setup the architecture | ||
262 | */ | ||
263 | static void __init | ||
264 | mpc85xx_cds_setup_arch(void) | ||
265 | { | ||
266 | struct device_node *cpu; | ||
267 | #ifdef CONFIG_PCI | ||
268 | struct device_node *np; | ||
269 | #endif | ||
270 | |||
271 | if (ppc_md.progress) | ||
272 | ppc_md.progress("mpc85xx_cds_setup_arch()", 0); | ||
273 | |||
274 | cpu = of_find_node_by_type(NULL, "cpu"); | ||
275 | if (cpu != 0) { | ||
276 | unsigned int *fp; | ||
277 | |||
278 | fp = (int *)get_property(cpu, "clock-frequency", NULL); | ||
279 | if (fp != 0) | ||
280 | loops_per_jiffy = *fp / HZ; | ||
281 | else | ||
282 | loops_per_jiffy = 500000000 / HZ; | ||
283 | of_node_put(cpu); | ||
284 | } | ||
285 | |||
286 | cadmus = ioremap(CADMUS_BASE, CADMUS_SIZE); | ||
287 | cds_pci_slot = ((cadmus[CM_CSR] >> 6) & 0x3) + 1; | ||
288 | |||
289 | if (ppc_md.progress) { | ||
290 | char buf[40]; | ||
291 | snprintf(buf, 40, "CDS Version = 0x%x in slot %d\n", | ||
292 | cadmus[CM_VER], cds_pci_slot); | ||
293 | ppc_md.progress(buf, 0); | ||
294 | } | ||
295 | |||
296 | #ifdef CONFIG_PCI | ||
297 | for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;) | ||
298 | add_bridge(np); | ||
299 | |||
300 | ppc_md.pcibios_fixup = mpc85xx_cds_pcibios_fixup; | ||
301 | ppc_md.pci_swizzle = common_swizzle; | ||
302 | ppc_md.pci_map_irq = mpc85xx_map_irq; | ||
303 | ppc_md.pci_exclude_device = mpc85xx_exclude_device; | ||
304 | #endif | ||
305 | |||
306 | #ifdef CONFIG_ROOT_NFS | ||
307 | ROOT_DEV = Root_NFS; | ||
308 | #else | ||
309 | ROOT_DEV = Root_HDA1; | ||
310 | #endif | ||
311 | } | ||
312 | |||
313 | |||
314 | void | ||
315 | mpc85xx_cds_show_cpuinfo(struct seq_file *m) | ||
316 | { | ||
317 | uint pvid, svid, phid1; | ||
318 | uint memsize = total_memory; | ||
319 | |||
320 | pvid = mfspr(SPRN_PVR); | ||
321 | svid = mfspr(SPRN_SVR); | ||
322 | |||
323 | seq_printf(m, "Vendor\t\t: Freescale Semiconductor\n"); | ||
324 | seq_printf(m, "Machine\t\t: MPC85xx CDS (0x%x)\n", cadmus[CM_VER]); | ||
325 | seq_printf(m, "PVR\t\t: 0x%x\n", pvid); | ||
326 | seq_printf(m, "SVR\t\t: 0x%x\n", svid); | ||
327 | |||
328 | /* Display cpu Pll setting */ | ||
329 | phid1 = mfspr(SPRN_HID1); | ||
330 | seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f)); | ||
331 | |||
332 | /* Display the amount of memory */ | ||
333 | seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024)); | ||
334 | } | ||
335 | |||
336 | |||
337 | /* | ||
338 | * Called very early, device-tree isn't unflattened | ||
339 | */ | ||
340 | static int __init mpc85xx_cds_probe(void) | ||
341 | { | ||
342 | /* We always match for now, eventually we should look at | ||
343 | * the flat dev tree to ensure this is the board we are | ||
344 | * supposed to run on | ||
345 | */ | ||
346 | return 1; | ||
347 | } | ||
348 | |||
349 | define_machine(mpc85xx_cds) { | ||
350 | .name = "MPC85xx CDS", | ||
351 | .probe = mpc85xx_cds_probe, | ||
352 | .setup_arch = mpc85xx_cds_setup_arch, | ||
353 | .init_IRQ = mpc85xx_cds_pic_init, | ||
354 | .show_cpuinfo = mpc85xx_cds_show_cpuinfo, | ||
355 | .get_irq = mpic_get_irq, | ||
356 | .restart = mpc85xx_restart, | ||
357 | .calibrate_decr = generic_calibrate_decr, | ||
358 | .progress = udbg_progress, | ||
359 | }; | ||
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_cds.h b/arch/powerpc/platforms/85xx/mpc85xx_cds.h new file mode 100644 index 000000000000..671f54ff185a --- /dev/null +++ b/arch/powerpc/platforms/85xx/mpc85xx_cds.h | |||
@@ -0,0 +1,43 @@ | |||
1 | /* | ||
2 | * arch/ppc/platforms/85xx/mpc85xx_cds_common.h | ||
3 | * | ||
4 | * MPC85xx CDS board definitions | ||
5 | * | ||
6 | * Maintainer: Kumar Gala <galak@kernel.crashing.org> | ||
7 | * | ||
8 | * Copyright 2004 Freescale Semiconductor, 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 | |||
17 | #ifndef __MACH_MPC85XX_CDS_H__ | ||
18 | #define __MACH_MPC85XX_CDS_H__ | ||
19 | |||
20 | /* CADMUS info */ | ||
21 | #define CADMUS_BASE (0xf8004000) | ||
22 | #define CADMUS_SIZE (256) | ||
23 | #define CM_VER (0) | ||
24 | #define CM_CSR (1) | ||
25 | #define CM_RST (2) | ||
26 | |||
27 | /* CDS NVRAM/RTC */ | ||
28 | #define CDS_RTC_ADDR (0xf8000000) | ||
29 | #define CDS_RTC_SIZE (8 * 1024) | ||
30 | |||
31 | /* PCI interrupt controller */ | ||
32 | #define PIRQ0A MPC85xx_IRQ_EXT0 | ||
33 | #define PIRQ0B MPC85xx_IRQ_EXT1 | ||
34 | #define PIRQ0C MPC85xx_IRQ_EXT2 | ||
35 | #define PIRQ0D MPC85xx_IRQ_EXT3 | ||
36 | #define PIRQ1A MPC85xx_IRQ_EXT11 | ||
37 | |||
38 | #define NR_8259_INTS 16 | ||
39 | #define CPM_IRQ_OFFSET NR_8259_INTS | ||
40 | |||
41 | #define MPC85xx_OPENPIC_IRQ_OFFSET 80 | ||
42 | |||
43 | #endif /* __MACH_MPC85XX_CDS_H__ */ | ||