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