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