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