12874c5fdSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
2e041013aSMartyn Welch /*
3e041013aSMartyn Welch * GE IMP3A Board Setup
4e041013aSMartyn Welch *
5e041013aSMartyn Welch * Author Martyn Welch <martyn.welch@ge.com>
6e041013aSMartyn Welch *
7e041013aSMartyn Welch * Copyright 2010 GE Intelligent Platforms Embedded Systems, Inc.
8e041013aSMartyn Welch *
9e041013aSMartyn Welch * Based on: mpc85xx_ds.c (MPC85xx DS Board Setup)
10e041013aSMartyn Welch * Copyright 2007 Freescale Semiconductor Inc.
11e041013aSMartyn Welch */
12e041013aSMartyn Welch
13e041013aSMartyn Welch #include <linux/stddef.h>
14e041013aSMartyn Welch #include <linux/kernel.h>
15e041013aSMartyn Welch #include <linux/pci.h>
16e041013aSMartyn Welch #include <linux/kdev_t.h>
17e041013aSMartyn Welch #include <linux/delay.h>
18e041013aSMartyn Welch #include <linux/seq_file.h>
19e041013aSMartyn Welch #include <linux/interrupt.h>
20*81d7cac4SRob Herring #include <linux/of.h>
21e6f6390aSChristophe Leroy #include <linux/of_address.h>
22e041013aSMartyn Welch
23e041013aSMartyn Welch #include <asm/time.h>
24e041013aSMartyn Welch #include <asm/machdep.h>
25e041013aSMartyn Welch #include <asm/pci-bridge.h>
26e041013aSMartyn Welch #include <mm/mmu_decl.h>
27e041013aSMartyn Welch #include <asm/udbg.h>
28e041013aSMartyn Welch #include <asm/mpic.h>
29e041013aSMartyn Welch #include <asm/swiotlb.h>
30e041013aSMartyn Welch #include <asm/nvram.h>
31e041013aSMartyn Welch
32e041013aSMartyn Welch #include <sysdev/fsl_soc.h>
33e041013aSMartyn Welch #include <sysdev/fsl_pci.h>
34e041013aSMartyn Welch #include "smp.h"
35e041013aSMartyn Welch
36e041013aSMartyn Welch #include "mpc85xx.h"
37e041013aSMartyn Welch #include <sysdev/ge/ge_pic.h>
38e041013aSMartyn Welch
39e041013aSMartyn Welch void __iomem *imp3a_regs;
40e041013aSMartyn Welch
ge_imp3a_pic_init(void)41e041013aSMartyn Welch void __init ge_imp3a_pic_init(void)
42e041013aSMartyn Welch {
43e041013aSMartyn Welch struct mpic *mpic;
44e041013aSMartyn Welch struct device_node *np;
45e041013aSMartyn Welch struct device_node *cascade_node = NULL;
46e041013aSMartyn Welch
47b2827883SBenjamin Herrenschmidt if (of_machine_is_compatible("fsl,MPC8572DS-CAMP")) {
48e041013aSMartyn Welch mpic = mpic_alloc(NULL, 0,
49e041013aSMartyn Welch MPIC_NO_RESET |
50e041013aSMartyn Welch MPIC_BIG_ENDIAN |
51e041013aSMartyn Welch MPIC_SINGLE_DEST_CPU,
52e041013aSMartyn Welch 0, 256, " OpenPIC ");
53e041013aSMartyn Welch } else {
54e041013aSMartyn Welch mpic = mpic_alloc(NULL, 0,
55e041013aSMartyn Welch MPIC_BIG_ENDIAN |
56e041013aSMartyn Welch MPIC_SINGLE_DEST_CPU,
57e041013aSMartyn Welch 0, 256, " OpenPIC ");
58e041013aSMartyn Welch }
59e041013aSMartyn Welch
60e041013aSMartyn Welch BUG_ON(mpic == NULL);
61e041013aSMartyn Welch mpic_init(mpic);
62e041013aSMartyn Welch /*
63e041013aSMartyn Welch * There is a simple interrupt handler in the main FPGA, this needs
64e041013aSMartyn Welch * to be cascaded into the MPIC
65e041013aSMartyn Welch */
66e041013aSMartyn Welch for_each_node_by_type(np, "interrupt-controller")
67e041013aSMartyn Welch if (of_device_is_compatible(np, "gef,fpga-pic-1.00")) {
68e041013aSMartyn Welch cascade_node = np;
69e041013aSMartyn Welch break;
70e041013aSMartyn Welch }
71e041013aSMartyn Welch
72e041013aSMartyn Welch if (cascade_node == NULL) {
73e041013aSMartyn Welch printk(KERN_WARNING "IMP3A: No FPGA PIC\n");
74e041013aSMartyn Welch return;
75e041013aSMartyn Welch }
76e041013aSMartyn Welch
77e041013aSMartyn Welch gef_pic_init(cascade_node);
78e041013aSMartyn Welch of_node_put(cascade_node);
79e041013aSMartyn Welch }
80e041013aSMartyn Welch
ge_imp3a_pci_assign_primary(void)81407454caSNick Child static void __init ge_imp3a_pci_assign_primary(void)
82905e75c4SJia Hongtao {
83e041013aSMartyn Welch #ifdef CONFIG_PCI
84905e75c4SJia Hongtao struct device_node *np;
85905e75c4SJia Hongtao struct resource rsrc;
86905e75c4SJia Hongtao
87905e75c4SJia Hongtao for_each_node_by_type(np, "pci") {
88905e75c4SJia Hongtao if (of_device_is_compatible(np, "fsl,mpc8540-pci") ||
89905e75c4SJia Hongtao of_device_is_compatible(np, "fsl,mpc8548-pcie") ||
90905e75c4SJia Hongtao of_device_is_compatible(np, "fsl,p2020-pcie")) {
91905e75c4SJia Hongtao of_address_to_resource(np, 0, &rsrc);
92a8b89c10SLiang He if ((rsrc.start & 0xfffff) == 0x9000) {
93a8b89c10SLiang He of_node_put(fsl_pci_primary);
94a8b89c10SLiang He fsl_pci_primary = of_node_get(np);
95a8b89c10SLiang He }
96905e75c4SJia Hongtao }
97905e75c4SJia Hongtao }
98905e75c4SJia Hongtao #endif
99905e75c4SJia Hongtao }
100e041013aSMartyn Welch
101e041013aSMartyn Welch /*
102e041013aSMartyn Welch * Setup the architecture
103e041013aSMartyn Welch */
ge_imp3a_setup_arch(void)104e041013aSMartyn Welch static void __init ge_imp3a_setup_arch(void)
105e041013aSMartyn Welch {
106e041013aSMartyn Welch struct device_node *regs;
107e041013aSMartyn Welch
108e041013aSMartyn Welch if (ppc_md.progress)
109e041013aSMartyn Welch ppc_md.progress("ge_imp3a_setup_arch()", 0);
110e041013aSMartyn Welch
111e041013aSMartyn Welch mpc85xx_smp_init();
112e041013aSMartyn Welch
113905e75c4SJia Hongtao ge_imp3a_pci_assign_primary();
114905e75c4SJia Hongtao
115905e75c4SJia Hongtao swiotlb_detect_4g();
116e041013aSMartyn Welch
117e041013aSMartyn Welch /* Remap basic board registers */
118e041013aSMartyn Welch regs = of_find_compatible_node(NULL, NULL, "ge,imp3a-fpga-regs");
119e041013aSMartyn Welch if (regs) {
120e041013aSMartyn Welch imp3a_regs = of_iomap(regs, 0);
121e041013aSMartyn Welch if (imp3a_regs == NULL)
122e041013aSMartyn Welch printk(KERN_WARNING "Unable to map board registers\n");
123e041013aSMartyn Welch of_node_put(regs);
124e041013aSMartyn Welch }
125e041013aSMartyn Welch
126e041013aSMartyn Welch #if defined(CONFIG_MMIO_NVRAM)
127e041013aSMartyn Welch mmio_nvram_init();
128e041013aSMartyn Welch #endif
129e041013aSMartyn Welch
130e041013aSMartyn Welch printk(KERN_INFO "GE Intelligent Platforms IMP3A 3U cPCI SBC\n");
131e041013aSMartyn Welch }
132e041013aSMartyn Welch
133e041013aSMartyn Welch /* Return the PCB revision */
ge_imp3a_get_pcb_rev(void)134e041013aSMartyn Welch static unsigned int ge_imp3a_get_pcb_rev(void)
135e041013aSMartyn Welch {
136e041013aSMartyn Welch unsigned int reg;
137e041013aSMartyn Welch
138e041013aSMartyn Welch reg = ioread16(imp3a_regs);
139e041013aSMartyn Welch return (reg >> 8) & 0xff;
140e041013aSMartyn Welch }
141e041013aSMartyn Welch
142e041013aSMartyn Welch /* Return the board (software) revision */
ge_imp3a_get_board_rev(void)143e041013aSMartyn Welch static unsigned int ge_imp3a_get_board_rev(void)
144e041013aSMartyn Welch {
145e041013aSMartyn Welch unsigned int reg;
146e041013aSMartyn Welch
147e041013aSMartyn Welch reg = ioread16(imp3a_regs + 0x2);
148e041013aSMartyn Welch return reg & 0xff;
149e041013aSMartyn Welch }
150e041013aSMartyn Welch
151e041013aSMartyn Welch /* Return the FPGA revision */
ge_imp3a_get_fpga_rev(void)152e041013aSMartyn Welch static unsigned int ge_imp3a_get_fpga_rev(void)
153e041013aSMartyn Welch {
154e041013aSMartyn Welch unsigned int reg;
155e041013aSMartyn Welch
156e041013aSMartyn Welch reg = ioread16(imp3a_regs + 0x2);
157e041013aSMartyn Welch return (reg >> 8) & 0xff;
158e041013aSMartyn Welch }
159e041013aSMartyn Welch
160e041013aSMartyn Welch /* Return compactPCI Geographical Address */
ge_imp3a_get_cpci_geo_addr(void)161e041013aSMartyn Welch static unsigned int ge_imp3a_get_cpci_geo_addr(void)
162e041013aSMartyn Welch {
163e041013aSMartyn Welch unsigned int reg;
164e041013aSMartyn Welch
165e041013aSMartyn Welch reg = ioread16(imp3a_regs + 0x6);
166e041013aSMartyn Welch return (reg & 0x0f00) >> 8;
167e041013aSMartyn Welch }
168e041013aSMartyn Welch
169e041013aSMartyn Welch /* Return compactPCI System Controller Status */
ge_imp3a_get_cpci_is_syscon(void)170e041013aSMartyn Welch static unsigned int ge_imp3a_get_cpci_is_syscon(void)
171e041013aSMartyn Welch {
172e041013aSMartyn Welch unsigned int reg;
173e041013aSMartyn Welch
174e041013aSMartyn Welch reg = ioread16(imp3a_regs + 0x6);
175e041013aSMartyn Welch return reg & (1 << 12);
176e041013aSMartyn Welch }
177e041013aSMartyn Welch
ge_imp3a_show_cpuinfo(struct seq_file * m)178e041013aSMartyn Welch static void ge_imp3a_show_cpuinfo(struct seq_file *m)
179e041013aSMartyn Welch {
180e041013aSMartyn Welch seq_printf(m, "Vendor\t\t: GE Intelligent Platforms\n");
181e041013aSMartyn Welch
182e041013aSMartyn Welch seq_printf(m, "Revision\t: %u%c\n", ge_imp3a_get_pcb_rev(),
183e041013aSMartyn Welch ('A' + ge_imp3a_get_board_rev() - 1));
184e041013aSMartyn Welch
185e041013aSMartyn Welch seq_printf(m, "FPGA Revision\t: %u\n", ge_imp3a_get_fpga_rev());
186e041013aSMartyn Welch
187e041013aSMartyn Welch seq_printf(m, "cPCI geo. addr\t: %u\n", ge_imp3a_get_cpci_geo_addr());
188e041013aSMartyn Welch
189e041013aSMartyn Welch seq_printf(m, "cPCI syscon\t: %s\n",
190e041013aSMartyn Welch ge_imp3a_get_cpci_is_syscon() ? "yes" : "no");
191e041013aSMartyn Welch }
192e041013aSMartyn Welch
193905e75c4SJia Hongtao machine_arch_initcall(ge_imp3a, mpc85xx_common_publish_devices);
194e041013aSMartyn Welch
define_machine(ge_imp3a)195e041013aSMartyn Welch define_machine(ge_imp3a) {
196e041013aSMartyn Welch .name = "GE_IMP3A",
1971c96fcdeSChristophe Leroy .compatible = "ge,IMP3A",
198e041013aSMartyn Welch .setup_arch = ge_imp3a_setup_arch,
199e041013aSMartyn Welch .init_IRQ = ge_imp3a_pic_init,
200e041013aSMartyn Welch .show_cpuinfo = ge_imp3a_show_cpuinfo,
201e041013aSMartyn Welch #ifdef CONFIG_PCI
202e041013aSMartyn Welch .pcibios_fixup_bus = fsl_pcibios_fixup_bus,
20348b16180SWang Dongsheng .pcibios_fixup_phb = fsl_pcibios_fixup_phb,
204e041013aSMartyn Welch #endif
205e041013aSMartyn Welch .get_irq = mpic_get_irq,
206e041013aSMartyn Welch .progress = udbg_progress,
207e041013aSMartyn Welch };
208