xref: /OK3568_Linux_fs/kernel/arch/powerpc/platforms/83xx/misc.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-or-later
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * misc setup functions for MPC83xx
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * Maintainer: Kumar Gala <galak@kernel.crashing.org>
6*4882a593Smuzhiyun  */
7*4882a593Smuzhiyun 
8*4882a593Smuzhiyun #include <linux/stddef.h>
9*4882a593Smuzhiyun #include <linux/kernel.h>
10*4882a593Smuzhiyun #include <linux/of_platform.h>
11*4882a593Smuzhiyun #include <linux/pci.h>
12*4882a593Smuzhiyun 
13*4882a593Smuzhiyun #include <asm/debug.h>
14*4882a593Smuzhiyun #include <asm/io.h>
15*4882a593Smuzhiyun #include <asm/hw_irq.h>
16*4882a593Smuzhiyun #include <asm/ipic.h>
17*4882a593Smuzhiyun #include <sysdev/fsl_soc.h>
18*4882a593Smuzhiyun #include <sysdev/fsl_pci.h>
19*4882a593Smuzhiyun 
20*4882a593Smuzhiyun #include <mm/mmu_decl.h>
21*4882a593Smuzhiyun 
22*4882a593Smuzhiyun #include "mpc83xx.h"
23*4882a593Smuzhiyun 
24*4882a593Smuzhiyun static __be32 __iomem *restart_reg_base;
25*4882a593Smuzhiyun 
mpc83xx_restart_init(void)26*4882a593Smuzhiyun static int __init mpc83xx_restart_init(void)
27*4882a593Smuzhiyun {
28*4882a593Smuzhiyun 	/* map reset restart_reg_baseister space */
29*4882a593Smuzhiyun 	restart_reg_base = ioremap(get_immrbase() + 0x900, 0xff);
30*4882a593Smuzhiyun 
31*4882a593Smuzhiyun 	return 0;
32*4882a593Smuzhiyun }
33*4882a593Smuzhiyun 
34*4882a593Smuzhiyun arch_initcall(mpc83xx_restart_init);
35*4882a593Smuzhiyun 
mpc83xx_restart(char * cmd)36*4882a593Smuzhiyun void __noreturn mpc83xx_restart(char *cmd)
37*4882a593Smuzhiyun {
38*4882a593Smuzhiyun #define RST_OFFSET	0x00000900
39*4882a593Smuzhiyun #define RST_PROT_REG	0x00000018
40*4882a593Smuzhiyun #define RST_CTRL_REG	0x0000001c
41*4882a593Smuzhiyun 
42*4882a593Smuzhiyun 	local_irq_disable();
43*4882a593Smuzhiyun 
44*4882a593Smuzhiyun 	if (restart_reg_base) {
45*4882a593Smuzhiyun 		/* enable software reset "RSTE" */
46*4882a593Smuzhiyun 		out_be32(restart_reg_base + (RST_PROT_REG >> 2), 0x52535445);
47*4882a593Smuzhiyun 
48*4882a593Smuzhiyun 		/* set software hard reset */
49*4882a593Smuzhiyun 		out_be32(restart_reg_base + (RST_CTRL_REG >> 2), 0x2);
50*4882a593Smuzhiyun 	} else {
51*4882a593Smuzhiyun 		printk (KERN_EMERG "Error: Restart registers not mapped, spinning!\n");
52*4882a593Smuzhiyun 	}
53*4882a593Smuzhiyun 
54*4882a593Smuzhiyun 	for (;;) ;
55*4882a593Smuzhiyun }
56*4882a593Smuzhiyun 
mpc83xx_time_init(void)57*4882a593Smuzhiyun long __init mpc83xx_time_init(void)
58*4882a593Smuzhiyun {
59*4882a593Smuzhiyun #define SPCR_OFFSET	0x00000110
60*4882a593Smuzhiyun #define SPCR_TBEN	0x00400000
61*4882a593Smuzhiyun 	__be32 __iomem *spcr = ioremap(get_immrbase() + SPCR_OFFSET, 4);
62*4882a593Smuzhiyun 	__be32 tmp;
63*4882a593Smuzhiyun 
64*4882a593Smuzhiyun 	tmp = in_be32(spcr);
65*4882a593Smuzhiyun 	out_be32(spcr, tmp | SPCR_TBEN);
66*4882a593Smuzhiyun 
67*4882a593Smuzhiyun 	iounmap(spcr);
68*4882a593Smuzhiyun 
69*4882a593Smuzhiyun 	return 0;
70*4882a593Smuzhiyun }
71*4882a593Smuzhiyun 
mpc83xx_ipic_init_IRQ(void)72*4882a593Smuzhiyun void __init mpc83xx_ipic_init_IRQ(void)
73*4882a593Smuzhiyun {
74*4882a593Smuzhiyun 	struct device_node *np;
75*4882a593Smuzhiyun 
76*4882a593Smuzhiyun 	/* looking for fsl,pq2pro-pic which is asl compatible with fsl,ipic */
77*4882a593Smuzhiyun 	np = of_find_compatible_node(NULL, NULL, "fsl,ipic");
78*4882a593Smuzhiyun 	if (!np)
79*4882a593Smuzhiyun 		np = of_find_node_by_type(NULL, "ipic");
80*4882a593Smuzhiyun 	if (!np)
81*4882a593Smuzhiyun 		return;
82*4882a593Smuzhiyun 
83*4882a593Smuzhiyun 	ipic_init(np, 0);
84*4882a593Smuzhiyun 
85*4882a593Smuzhiyun 	of_node_put(np);
86*4882a593Smuzhiyun 
87*4882a593Smuzhiyun 	/* Initialize the default interrupt mapping priorities,
88*4882a593Smuzhiyun 	 * in case the boot rom changed something on us.
89*4882a593Smuzhiyun 	 */
90*4882a593Smuzhiyun 	ipic_set_default_priority();
91*4882a593Smuzhiyun }
92*4882a593Smuzhiyun 
93*4882a593Smuzhiyun static const struct of_device_id of_bus_ids[] __initconst = {
94*4882a593Smuzhiyun 	{ .type = "soc", },
95*4882a593Smuzhiyun 	{ .compatible = "soc", },
96*4882a593Smuzhiyun 	{ .compatible = "simple-bus" },
97*4882a593Smuzhiyun 	{ .compatible = "gianfar" },
98*4882a593Smuzhiyun 	{ .compatible = "gpio-leds", },
99*4882a593Smuzhiyun 	{ .type = "qe", },
100*4882a593Smuzhiyun 	{ .compatible = "fsl,qe", },
101*4882a593Smuzhiyun 	{},
102*4882a593Smuzhiyun };
103*4882a593Smuzhiyun 
mpc83xx_declare_of_platform_devices(void)104*4882a593Smuzhiyun int __init mpc83xx_declare_of_platform_devices(void)
105*4882a593Smuzhiyun {
106*4882a593Smuzhiyun 	of_platform_bus_probe(NULL, of_bus_ids, NULL);
107*4882a593Smuzhiyun 	return 0;
108*4882a593Smuzhiyun }
109*4882a593Smuzhiyun 
110*4882a593Smuzhiyun #ifdef CONFIG_PCI
mpc83xx_setup_pci(void)111*4882a593Smuzhiyun void __init mpc83xx_setup_pci(void)
112*4882a593Smuzhiyun {
113*4882a593Smuzhiyun 	struct device_node *np;
114*4882a593Smuzhiyun 
115*4882a593Smuzhiyun 	for_each_compatible_node(np, "pci", "fsl,mpc8349-pci")
116*4882a593Smuzhiyun 		mpc83xx_add_bridge(np);
117*4882a593Smuzhiyun 	for_each_compatible_node(np, "pci", "fsl,mpc8314-pcie")
118*4882a593Smuzhiyun 		mpc83xx_add_bridge(np);
119*4882a593Smuzhiyun }
120*4882a593Smuzhiyun #endif
121*4882a593Smuzhiyun 
mpc83xx_setup_arch(void)122*4882a593Smuzhiyun void __init mpc83xx_setup_arch(void)
123*4882a593Smuzhiyun {
124*4882a593Smuzhiyun 	if (ppc_md.progress)
125*4882a593Smuzhiyun 		ppc_md.progress("mpc83xx_setup_arch()", 0);
126*4882a593Smuzhiyun 
127*4882a593Smuzhiyun 	if (!__map_without_bats) {
128*4882a593Smuzhiyun 		phys_addr_t immrbase = get_immrbase();
129*4882a593Smuzhiyun 		int immrsize = IS_ALIGNED(immrbase, SZ_2M) ? SZ_2M : SZ_1M;
130*4882a593Smuzhiyun 		unsigned long va = fix_to_virt(FIX_IMMR_BASE);
131*4882a593Smuzhiyun 
132*4882a593Smuzhiyun 		setbat(-1, va, immrbase, immrsize, PAGE_KERNEL_NCG);
133*4882a593Smuzhiyun 		update_bats();
134*4882a593Smuzhiyun 	}
135*4882a593Smuzhiyun 
136*4882a593Smuzhiyun 	mpc83xx_setup_pci();
137*4882a593Smuzhiyun }
138*4882a593Smuzhiyun 
machine_check_83xx(struct pt_regs * regs)139*4882a593Smuzhiyun int machine_check_83xx(struct pt_regs *regs)
140*4882a593Smuzhiyun {
141*4882a593Smuzhiyun 	u32 mask = 1 << (31 - IPIC_MCP_WDT);
142*4882a593Smuzhiyun 
143*4882a593Smuzhiyun 	if (!(regs->msr & SRR1_MCE_MCP) || !(ipic_get_mcp_status() & mask))
144*4882a593Smuzhiyun 		return machine_check_generic(regs);
145*4882a593Smuzhiyun 	ipic_clear_mcp_status(mask);
146*4882a593Smuzhiyun 
147*4882a593Smuzhiyun 	if (debugger_fault_handler(regs))
148*4882a593Smuzhiyun 		return 1;
149*4882a593Smuzhiyun 
150*4882a593Smuzhiyun 	die("Watchdog NMI Reset", regs, 0);
151*4882a593Smuzhiyun 
152*4882a593Smuzhiyun 	return 1;
153*4882a593Smuzhiyun }
154