Merge branch 'pm-opp'
[firefly-linux-kernel-4.4.55.git] / arch / powerpc / platforms / 85xx / corenet_generic.c
1 /*
2  * Corenet based SoC DS Setup
3  *
4  * Maintained by Kumar Gala (see MAINTAINERS for contact information)
5  *
6  * Copyright 2009-2011 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/kernel.h>
15 #include <linux/pci.h>
16 #include <linux/kdev_t.h>
17 #include <linux/delay.h>
18 #include <linux/interrupt.h>
19
20 #include <asm/time.h>
21 #include <asm/machdep.h>
22 #include <asm/pci-bridge.h>
23 #include <asm/pgtable.h>
24 #include <asm/ppc-pci.h>
25 #include <mm/mmu_decl.h>
26 #include <asm/prom.h>
27 #include <asm/udbg.h>
28 #include <asm/mpic.h>
29 #include <asm/ehv_pic.h>
30 #include <asm/qe_ic.h>
31
32 #include <linux/of_platform.h>
33 #include <sysdev/fsl_soc.h>
34 #include <sysdev/fsl_pci.h>
35 #include "smp.h"
36 #include "mpc85xx.h"
37
38 void __init corenet_gen_pic_init(void)
39 {
40         struct mpic *mpic;
41         unsigned int flags = MPIC_BIG_ENDIAN | MPIC_SINGLE_DEST_CPU |
42                 MPIC_NO_RESET;
43
44         struct device_node *np;
45
46         if (ppc_md.get_irq == mpic_get_coreint_irq)
47                 flags |= MPIC_ENABLE_COREINT;
48
49         mpic = mpic_alloc(NULL, 0, flags, 0, 512, " OpenPIC  ");
50         BUG_ON(mpic == NULL);
51
52         mpic_init(mpic);
53
54         np = of_find_compatible_node(NULL, NULL, "fsl,qe-ic");
55         if (np) {
56                 qe_ic_init(np, 0, qe_ic_cascade_low_mpic,
57                                 qe_ic_cascade_high_mpic);
58                 of_node_put(np);
59         }
60 }
61
62 /*
63  * Setup the architecture
64  */
65 void __init corenet_gen_setup_arch(void)
66 {
67         mpc85xx_smp_init();
68
69         swiotlb_detect_4g();
70
71 #if defined(CONFIG_FSL_PCI) && defined(CONFIG_ZONE_DMA32)
72         /*
73          * Inbound windows don't cover the full lower 4 GiB
74          * due to conflicts with PCICSRBAR and outbound windows,
75          * so limit the DMA32 zone to 2 GiB, to allow consistent
76          * allocations to succeed.
77          */
78         limit_zone_pfn(ZONE_DMA32, 1UL << (31 - PAGE_SHIFT));
79 #endif
80
81         pr_info("%s board\n", ppc_md.name);
82
83         mpc85xx_qe_init();
84 }
85
86 static const struct of_device_id of_device_ids[] = {
87         {
88                 .compatible     = "simple-bus"
89         },
90         {
91                 .compatible     = "mdio-mux-gpio"
92         },
93         {
94                 .compatible     = "fsl,fpga-ngpixis"
95         },
96         {
97                 .compatible     = "fsl,fpga-qixis"
98         },
99         {
100                 .compatible     = "fsl,srio",
101         },
102         {
103                 .compatible     = "fsl,p4080-pcie",
104         },
105         {
106                 .compatible     = "fsl,qoriq-pcie-v2.2",
107         },
108         {
109                 .compatible     = "fsl,qoriq-pcie-v2.3",
110         },
111         {
112                 .compatible     = "fsl,qoriq-pcie-v2.4",
113         },
114         {
115                 .compatible     = "fsl,qoriq-pcie-v3.0",
116         },
117         {
118                 .compatible     = "fsl,qe",
119         },
120         {
121                 .compatible    = "fsl,fman",
122         },
123         /* The following two are for the Freescale hypervisor */
124         {
125                 .name           = "hypervisor",
126         },
127         {
128                 .name           = "handles",
129         },
130         {}
131 };
132
133 int __init corenet_gen_publish_devices(void)
134 {
135         return of_platform_bus_probe(NULL, of_device_ids, NULL);
136 }
137
138 static const char * const boards[] __initconst = {
139         "fsl,P2041RDB",
140         "fsl,P3041DS",
141         "fsl,OCA4080",
142         "fsl,P4080DS",
143         "fsl,P5020DS",
144         "fsl,P5040DS",
145         "fsl,T2080QDS",
146         "fsl,T2080RDB",
147         "fsl,T2081QDS",
148         "fsl,T4240QDS",
149         "fsl,T4240RDB",
150         "fsl,B4860QDS",
151         "fsl,B4420QDS",
152         "fsl,B4220QDS",
153         "fsl,T1023RDB",
154         "fsl,T1024QDS",
155         "fsl,T1024RDB",
156         "fsl,T1040D4RDB",
157         "fsl,T1042D4RDB",
158         "fsl,T1040QDS",
159         "fsl,T1042QDS",
160         "fsl,T1040RDB",
161         "fsl,T1042RDB",
162         "fsl,T1042RDB_PI",
163         "keymile,kmcoge4",
164         NULL
165 };
166
167 /*
168  * Called very early, device-tree isn't unflattened
169  */
170 static int __init corenet_generic_probe(void)
171 {
172         unsigned long root = of_get_flat_dt_root();
173         char hv_compat[24];
174         int i;
175 #ifdef CONFIG_SMP
176         extern struct smp_ops_t smp_85xx_ops;
177 #endif
178
179         if (of_flat_dt_match(root, boards))
180                 return 1;
181
182         /* Check if we're running under the Freescale hypervisor */
183         for (i = 0; boards[i]; i++) {
184                 snprintf(hv_compat, sizeof(hv_compat), "%s-hv", boards[i]);
185                 if (of_flat_dt_is_compatible(root, hv_compat)) {
186                         ppc_md.init_IRQ = ehv_pic_init;
187
188                         ppc_md.get_irq = ehv_pic_get_irq;
189                         ppc_md.restart = fsl_hv_restart;
190                         pm_power_off = fsl_hv_halt;
191                         ppc_md.halt = fsl_hv_halt;
192 #ifdef CONFIG_SMP
193                         /*
194                          * Disable the timebase sync operations because we
195                          * can't write to the timebase registers under the
196                          * hypervisor.
197                          */
198                         smp_85xx_ops.give_timebase = NULL;
199                         smp_85xx_ops.take_timebase = NULL;
200 #endif
201                         return 1;
202                 }
203         }
204
205         return 0;
206 }
207
208 define_machine(corenet_generic) {
209         .name                   = "CoreNet Generic",
210         .probe                  = corenet_generic_probe,
211         .setup_arch             = corenet_gen_setup_arch,
212         .init_IRQ               = corenet_gen_pic_init,
213 #ifdef CONFIG_PCI
214         .pcibios_fixup_bus      = fsl_pcibios_fixup_bus,
215         .pcibios_fixup_phb      = fsl_pcibios_fixup_phb,
216 #endif
217         .get_irq                = mpic_get_coreint_irq,
218         .restart                = fsl_rstcr_restart,
219         .calibrate_decr         = generic_calibrate_decr,
220         .progress               = udbg_progress,
221 #ifdef CONFIG_PPC64
222         .power_save             = book3e_idle,
223 #else
224         .power_save             = e500_idle,
225 #endif
226 };
227
228 machine_arch_initcall(corenet_generic, corenet_gen_publish_devices);
229
230 #ifdef CONFIG_SWIOTLB
231 machine_arch_initcall(corenet_generic, swiotlb_setup_bus_notifier);
232 #endif