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