Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc
[firefly-linux-kernel-4.4.55.git] / arch / powerpc / platforms / 85xx / ge_imp3a.c
1 /*
2  * GE IMP3A Board Setup
3  *
4  * Author Martyn Welch <martyn.welch@ge.com>
5  *
6  * Copyright 2010 GE Intelligent Platforms Embedded Systems, 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  * Based on: mpc85xx_ds.c (MPC85xx DS Board Setup)
14  * Copyright 2007 Freescale Semiconductor Inc.
15  */
16
17 #include <linux/stddef.h>
18 #include <linux/kernel.h>
19 #include <linux/pci.h>
20 #include <linux/kdev_t.h>
21 #include <linux/delay.h>
22 #include <linux/seq_file.h>
23 #include <linux/interrupt.h>
24 #include <linux/of_platform.h>
25 #include <linux/memblock.h>
26
27 #include <asm/system.h>
28 #include <asm/time.h>
29 #include <asm/machdep.h>
30 #include <asm/pci-bridge.h>
31 #include <mm/mmu_decl.h>
32 #include <asm/prom.h>
33 #include <asm/udbg.h>
34 #include <asm/mpic.h>
35 #include <asm/swiotlb.h>
36 #include <asm/nvram.h>
37
38 #include <sysdev/fsl_soc.h>
39 #include <sysdev/fsl_pci.h>
40 #include "smp.h"
41
42 #include "mpc85xx.h"
43 #include <sysdev/ge/ge_pic.h>
44
45 void __iomem *imp3a_regs;
46
47 void __init ge_imp3a_pic_init(void)
48 {
49         struct mpic *mpic;
50         struct device_node *np;
51         struct device_node *cascade_node = NULL;
52         unsigned long root = of_get_flat_dt_root();
53
54         if (of_flat_dt_is_compatible(root, "fsl,MPC8572DS-CAMP")) {
55                 mpic = mpic_alloc(NULL, 0,
56                         MPIC_NO_RESET |
57                         MPIC_BIG_ENDIAN |
58                         MPIC_SINGLE_DEST_CPU,
59                         0, 256, " OpenPIC  ");
60         } else {
61                 mpic = mpic_alloc(NULL, 0,
62                           MPIC_BIG_ENDIAN |
63                           MPIC_SINGLE_DEST_CPU,
64                         0, 256, " OpenPIC  ");
65         }
66
67         BUG_ON(mpic == NULL);
68         mpic_init(mpic);
69         /*
70          * There is a simple interrupt handler in the main FPGA, this needs
71          * to be cascaded into the MPIC
72          */
73         for_each_node_by_type(np, "interrupt-controller")
74                 if (of_device_is_compatible(np, "gef,fpga-pic-1.00")) {
75                         cascade_node = np;
76                         break;
77                 }
78
79         if (cascade_node == NULL) {
80                 printk(KERN_WARNING "IMP3A: No FPGA PIC\n");
81                 return;
82         }
83
84         gef_pic_init(cascade_node);
85         of_node_put(cascade_node);
86 }
87
88 #ifdef CONFIG_PCI
89 static int primary_phb_addr;
90 #endif  /* CONFIG_PCI */
91
92 /*
93  * Setup the architecture
94  */
95 static void __init ge_imp3a_setup_arch(void)
96 {
97         struct device_node *regs;
98 #ifdef CONFIG_PCI
99         struct device_node *np;
100         struct pci_controller *hose;
101 #endif
102         dma_addr_t max = 0xffffffff;
103
104         if (ppc_md.progress)
105                 ppc_md.progress("ge_imp3a_setup_arch()", 0);
106
107 #ifdef CONFIG_PCI
108         for_each_node_by_type(np, "pci") {
109                 if (of_device_is_compatible(np, "fsl,mpc8540-pci") ||
110                     of_device_is_compatible(np, "fsl,mpc8548-pcie") ||
111                     of_device_is_compatible(np, "fsl,p2020-pcie")) {
112                         struct resource rsrc;
113                         of_address_to_resource(np, 0, &rsrc);
114                         if ((rsrc.start & 0xfffff) == primary_phb_addr)
115                                 fsl_add_bridge(np, 1);
116                         else
117                                 fsl_add_bridge(np, 0);
118
119                         hose = pci_find_hose_for_OF_device(np);
120                         max = min(max, hose->dma_window_base_cur +
121                                         hose->dma_window_size);
122                 }
123         }
124 #endif
125
126         mpc85xx_smp_init();
127
128 #ifdef CONFIG_SWIOTLB
129         if (memblock_end_of_DRAM() > max) {
130                 ppc_swiotlb_enable = 1;
131                 set_pci_dma_ops(&swiotlb_dma_ops);
132                 ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb;
133         }
134 #endif
135
136         /* Remap basic board registers */
137         regs = of_find_compatible_node(NULL, NULL, "ge,imp3a-fpga-regs");
138         if (regs) {
139                 imp3a_regs = of_iomap(regs, 0);
140                 if (imp3a_regs == NULL)
141                         printk(KERN_WARNING "Unable to map board registers\n");
142                 of_node_put(regs);
143         }
144
145 #if defined(CONFIG_MMIO_NVRAM)
146         mmio_nvram_init();
147 #endif
148
149         printk(KERN_INFO "GE Intelligent Platforms IMP3A 3U cPCI SBC\n");
150 }
151
152 /* Return the PCB revision */
153 static unsigned int ge_imp3a_get_pcb_rev(void)
154 {
155         unsigned int reg;
156
157         reg = ioread16(imp3a_regs);
158         return (reg >> 8) & 0xff;
159 }
160
161 /* Return the board (software) revision */
162 static unsigned int ge_imp3a_get_board_rev(void)
163 {
164         unsigned int reg;
165
166         reg = ioread16(imp3a_regs + 0x2);
167         return reg & 0xff;
168 }
169
170 /* Return the FPGA revision */
171 static unsigned int ge_imp3a_get_fpga_rev(void)
172 {
173         unsigned int reg;
174
175         reg = ioread16(imp3a_regs + 0x2);
176         return (reg >> 8) & 0xff;
177 }
178
179 /* Return compactPCI Geographical Address */
180 static unsigned int ge_imp3a_get_cpci_geo_addr(void)
181 {
182         unsigned int reg;
183
184         reg = ioread16(imp3a_regs + 0x6);
185         return (reg & 0x0f00) >> 8;
186 }
187
188 /* Return compactPCI System Controller Status */
189 static unsigned int ge_imp3a_get_cpci_is_syscon(void)
190 {
191         unsigned int reg;
192
193         reg = ioread16(imp3a_regs + 0x6);
194         return reg & (1 << 12);
195 }
196
197 static void ge_imp3a_show_cpuinfo(struct seq_file *m)
198 {
199         seq_printf(m, "Vendor\t\t: GE Intelligent Platforms\n");
200
201         seq_printf(m, "Revision\t: %u%c\n", ge_imp3a_get_pcb_rev(),
202                 ('A' + ge_imp3a_get_board_rev() - 1));
203
204         seq_printf(m, "FPGA Revision\t: %u\n", ge_imp3a_get_fpga_rev());
205
206         seq_printf(m, "cPCI geo. addr\t: %u\n", ge_imp3a_get_cpci_geo_addr());
207
208         seq_printf(m, "cPCI syscon\t: %s\n",
209                 ge_imp3a_get_cpci_is_syscon() ? "yes" : "no");
210 }
211
212 /*
213  * Called very early, device-tree isn't unflattened
214  */
215 static int __init ge_imp3a_probe(void)
216 {
217         unsigned long root = of_get_flat_dt_root();
218
219         if (of_flat_dt_is_compatible(root, "ge,IMP3A")) {
220 #ifdef CONFIG_PCI
221                 primary_phb_addr = 0x9000;
222 #endif
223                 return 1;
224         }
225
226         return 0;
227 }
228
229 machine_device_initcall(ge_imp3a, mpc85xx_common_publish_devices);
230
231 machine_arch_initcall(ge_imp3a, swiotlb_setup_bus_notifier);
232
233 define_machine(ge_imp3a) {
234         .name                   = "GE_IMP3A",
235         .probe                  = ge_imp3a_probe,
236         .setup_arch             = ge_imp3a_setup_arch,
237         .init_IRQ               = ge_imp3a_pic_init,
238         .show_cpuinfo           = ge_imp3a_show_cpuinfo,
239 #ifdef CONFIG_PCI
240         .pcibios_fixup_bus      = fsl_pcibios_fixup_bus,
241 #endif
242         .get_irq                = mpic_get_irq,
243         .restart                = fsl_rstcr_restart,
244         .calibrate_decr         = generic_calibrate_decr,
245         .progress               = udbg_progress,
246 };