162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * misc setup functions for MPC83xx
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Maintainer: Kumar Gala <galak@kernel.crashing.org>
662306a36Sopenharmony_ci */
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci#include <linux/stddef.h>
962306a36Sopenharmony_ci#include <linux/kernel.h>
1062306a36Sopenharmony_ci#include <linux/of_platform.h>
1162306a36Sopenharmony_ci#include <linux/pci.h>
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ci#include <asm/debug.h>
1462306a36Sopenharmony_ci#include <asm/io.h>
1562306a36Sopenharmony_ci#include <asm/hw_irq.h>
1662306a36Sopenharmony_ci#include <asm/ipic.h>
1762306a36Sopenharmony_ci#include <sysdev/fsl_soc.h>
1862306a36Sopenharmony_ci#include <sysdev/fsl_pci.h>
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_ci#include <mm/mmu_decl.h>
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_ci#include "mpc83xx.h"
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_cistatic __be32 __iomem *restart_reg_base;
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_cistatic int __init mpc83xx_restart_init(void)
2762306a36Sopenharmony_ci{
2862306a36Sopenharmony_ci	/* map reset restart_reg_baseister space */
2962306a36Sopenharmony_ci	restart_reg_base = ioremap(get_immrbase() + 0x900, 0xff);
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_ci	return 0;
3262306a36Sopenharmony_ci}
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_ciarch_initcall(mpc83xx_restart_init);
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_civoid __noreturn mpc83xx_restart(char *cmd)
3762306a36Sopenharmony_ci{
3862306a36Sopenharmony_ci#define RST_OFFSET	0x00000900
3962306a36Sopenharmony_ci#define RST_PROT_REG	0x00000018
4062306a36Sopenharmony_ci#define RST_CTRL_REG	0x0000001c
4162306a36Sopenharmony_ci
4262306a36Sopenharmony_ci	local_irq_disable();
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_ci	if (restart_reg_base) {
4562306a36Sopenharmony_ci		/* enable software reset "RSTE" */
4662306a36Sopenharmony_ci		out_be32(restart_reg_base + (RST_PROT_REG >> 2), 0x52535445);
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_ci		/* set software hard reset */
4962306a36Sopenharmony_ci		out_be32(restart_reg_base + (RST_CTRL_REG >> 2), 0x2);
5062306a36Sopenharmony_ci	} else {
5162306a36Sopenharmony_ci		printk (KERN_EMERG "Error: Restart registers not mapped, spinning!\n");
5262306a36Sopenharmony_ci	}
5362306a36Sopenharmony_ci
5462306a36Sopenharmony_ci	for (;;) ;
5562306a36Sopenharmony_ci}
5662306a36Sopenharmony_ci
5762306a36Sopenharmony_cilong __init mpc83xx_time_init(void)
5862306a36Sopenharmony_ci{
5962306a36Sopenharmony_ci#define SPCR_OFFSET	0x00000110
6062306a36Sopenharmony_ci#define SPCR_TBEN	0x00400000
6162306a36Sopenharmony_ci	__be32 __iomem *spcr = ioremap(get_immrbase() + SPCR_OFFSET, 4);
6262306a36Sopenharmony_ci	__be32 tmp;
6362306a36Sopenharmony_ci
6462306a36Sopenharmony_ci	tmp = in_be32(spcr);
6562306a36Sopenharmony_ci	out_be32(spcr, tmp | SPCR_TBEN);
6662306a36Sopenharmony_ci
6762306a36Sopenharmony_ci	iounmap(spcr);
6862306a36Sopenharmony_ci
6962306a36Sopenharmony_ci	return 0;
7062306a36Sopenharmony_ci}
7162306a36Sopenharmony_ci
7262306a36Sopenharmony_civoid __init mpc83xx_ipic_init_IRQ(void)
7362306a36Sopenharmony_ci{
7462306a36Sopenharmony_ci	struct device_node *np;
7562306a36Sopenharmony_ci
7662306a36Sopenharmony_ci	/* looking for fsl,pq2pro-pic which is asl compatible with fsl,ipic */
7762306a36Sopenharmony_ci	np = of_find_compatible_node(NULL, NULL, "fsl,ipic");
7862306a36Sopenharmony_ci	if (!np)
7962306a36Sopenharmony_ci		np = of_find_node_by_type(NULL, "ipic");
8062306a36Sopenharmony_ci	if (!np)
8162306a36Sopenharmony_ci		return;
8262306a36Sopenharmony_ci
8362306a36Sopenharmony_ci	ipic_init(np, 0);
8462306a36Sopenharmony_ci
8562306a36Sopenharmony_ci	of_node_put(np);
8662306a36Sopenharmony_ci
8762306a36Sopenharmony_ci	/* Initialize the default interrupt mapping priorities,
8862306a36Sopenharmony_ci	 * in case the boot rom changed something on us.
8962306a36Sopenharmony_ci	 */
9062306a36Sopenharmony_ci	ipic_set_default_priority();
9162306a36Sopenharmony_ci}
9262306a36Sopenharmony_ci
9362306a36Sopenharmony_cistatic const struct of_device_id of_bus_ids[] __initconst = {
9462306a36Sopenharmony_ci	{ .type = "soc", },
9562306a36Sopenharmony_ci	{ .compatible = "soc", },
9662306a36Sopenharmony_ci	{ .compatible = "simple-bus" },
9762306a36Sopenharmony_ci	{ .compatible = "gianfar" },
9862306a36Sopenharmony_ci	{ .compatible = "gpio-leds", },
9962306a36Sopenharmony_ci	{ .type = "qe", },
10062306a36Sopenharmony_ci	{ .compatible = "fsl,qe", },
10162306a36Sopenharmony_ci	{},
10262306a36Sopenharmony_ci};
10362306a36Sopenharmony_ci
10462306a36Sopenharmony_ciint __init mpc83xx_declare_of_platform_devices(void)
10562306a36Sopenharmony_ci{
10662306a36Sopenharmony_ci	of_platform_bus_probe(NULL, of_bus_ids, NULL);
10762306a36Sopenharmony_ci	return 0;
10862306a36Sopenharmony_ci}
10962306a36Sopenharmony_ci
11062306a36Sopenharmony_ci#ifdef CONFIG_PCI
11162306a36Sopenharmony_civoid __init mpc83xx_setup_pci(void)
11262306a36Sopenharmony_ci{
11362306a36Sopenharmony_ci	struct device_node *np;
11462306a36Sopenharmony_ci
11562306a36Sopenharmony_ci	for_each_compatible_node(np, "pci", "fsl,mpc8349-pci")
11662306a36Sopenharmony_ci		mpc83xx_add_bridge(np);
11762306a36Sopenharmony_ci	for_each_compatible_node(np, "pci", "fsl,mpc8314-pcie")
11862306a36Sopenharmony_ci		mpc83xx_add_bridge(np);
11962306a36Sopenharmony_ci}
12062306a36Sopenharmony_ci#endif
12162306a36Sopenharmony_ci
12262306a36Sopenharmony_civoid __init mpc83xx_setup_arch(void)
12362306a36Sopenharmony_ci{
12462306a36Sopenharmony_ci	phys_addr_t immrbase = get_immrbase();
12562306a36Sopenharmony_ci	int immrsize = IS_ALIGNED(immrbase, SZ_2M) ? SZ_2M : SZ_1M;
12662306a36Sopenharmony_ci	unsigned long va = fix_to_virt(FIX_IMMR_BASE);
12762306a36Sopenharmony_ci
12862306a36Sopenharmony_ci	if (ppc_md.progress)
12962306a36Sopenharmony_ci		ppc_md.progress("mpc83xx_setup_arch()", 0);
13062306a36Sopenharmony_ci
13162306a36Sopenharmony_ci	setbat(-1, va, immrbase, immrsize, PAGE_KERNEL_NCG);
13262306a36Sopenharmony_ci	update_bats();
13362306a36Sopenharmony_ci}
13462306a36Sopenharmony_ci
13562306a36Sopenharmony_ciint machine_check_83xx(struct pt_regs *regs)
13662306a36Sopenharmony_ci{
13762306a36Sopenharmony_ci	u32 mask = 1 << (31 - IPIC_MCP_WDT);
13862306a36Sopenharmony_ci
13962306a36Sopenharmony_ci	if (!(regs->msr & SRR1_MCE_MCP) || !(ipic_get_mcp_status() & mask))
14062306a36Sopenharmony_ci		return machine_check_generic(regs);
14162306a36Sopenharmony_ci	ipic_clear_mcp_status(mask);
14262306a36Sopenharmony_ci
14362306a36Sopenharmony_ci	if (debugger_fault_handler(regs))
14462306a36Sopenharmony_ci		return 1;
14562306a36Sopenharmony_ci
14662306a36Sopenharmony_ci	die("Watchdog NMI Reset", regs, 0);
14762306a36Sopenharmony_ci
14862306a36Sopenharmony_ci	return 1;
14962306a36Sopenharmony_ci}
150