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