12874c5fdSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later 2740d36aeSMartyn Welch /* 3948e78c3SMartyn Welch * GE PPC9A board support 4740d36aeSMartyn Welch * 5948e78c3SMartyn Welch * Author: Martyn Welch <martyn.welch@ge.com> 6740d36aeSMartyn Welch * 7948e78c3SMartyn Welch * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc. 8740d36aeSMartyn Welch * 9740d36aeSMartyn Welch * Based on: mpc86xx_hpcn.c (MPC86xx HPCN board specific routines) 10740d36aeSMartyn Welch * Copyright 2006 Freescale Semiconductor Inc. 11740d36aeSMartyn Welch * 12740d36aeSMartyn Welch * NEC fixup adapted from arch/mips/pci/fixup-lm2e.c 13740d36aeSMartyn Welch */ 14740d36aeSMartyn Welch 15740d36aeSMartyn Welch #include <linux/stddef.h> 16740d36aeSMartyn Welch #include <linux/kernel.h> 17740d36aeSMartyn Welch #include <linux/pci.h> 18740d36aeSMartyn Welch #include <linux/kdev_t.h> 19740d36aeSMartyn Welch #include <linux/delay.h> 20740d36aeSMartyn Welch #include <linux/seq_file.h> 21*81d7cac4SRob Herring #include <linux/of.h> 22e6f6390aSChristophe Leroy #include <linux/of_address.h> 23740d36aeSMartyn Welch 24740d36aeSMartyn Welch #include <asm/time.h> 25740d36aeSMartyn Welch #include <asm/machdep.h> 26740d36aeSMartyn Welch #include <asm/pci-bridge.h> 27740d36aeSMartyn Welch #include <mm/mmu_decl.h> 28740d36aeSMartyn Welch #include <asm/udbg.h> 29740d36aeSMartyn Welch 30740d36aeSMartyn Welch #include <asm/mpic.h> 313bc26562SMartyn Welch #include <asm/nvram.h> 32740d36aeSMartyn Welch 33740d36aeSMartyn Welch #include <sysdev/fsl_pci.h> 34740d36aeSMartyn Welch #include <sysdev/fsl_soc.h> 3544b24b74SMartyn Welch #include <sysdev/ge/ge_pic.h> 36740d36aeSMartyn Welch 37740d36aeSMartyn Welch #include "mpc86xx.h" 38740d36aeSMartyn Welch 39740d36aeSMartyn Welch #undef DEBUG 40740d36aeSMartyn Welch 41740d36aeSMartyn Welch #ifdef DEBUG 42740d36aeSMartyn Welch #define DBG (fmt...) do { printk(KERN_ERR "PPC9A: " fmt); } while (0) 43740d36aeSMartyn Welch #else 44740d36aeSMartyn Welch #define DBG (fmt...) do { } while (0) 45740d36aeSMartyn Welch #endif 46740d36aeSMartyn Welch 47740d36aeSMartyn Welch void __iomem *ppc9a_regs; 48740d36aeSMartyn Welch 49740d36aeSMartyn Welch static void __init gef_ppc9a_init_irq(void) 50740d36aeSMartyn Welch { 51740d36aeSMartyn Welch struct device_node *cascade_node = NULL; 52740d36aeSMartyn Welch 53740d36aeSMartyn Welch mpc86xx_init_irq(); 54740d36aeSMartyn Welch 55740d36aeSMartyn Welch /* 56740d36aeSMartyn Welch * There is a simple interrupt handler in the main FPGA, this needs 57740d36aeSMartyn Welch * to be cascaded into the MPIC 58740d36aeSMartyn Welch */ 59740d36aeSMartyn Welch cascade_node = of_find_compatible_node(NULL, NULL, "gef,fpga-pic-1.00"); 60740d36aeSMartyn Welch if (!cascade_node) { 61740d36aeSMartyn Welch printk(KERN_WARNING "PPC9A: No FPGA PIC\n"); 62740d36aeSMartyn Welch return; 63740d36aeSMartyn Welch } 64740d36aeSMartyn Welch 65740d36aeSMartyn Welch gef_pic_init(cascade_node); 66740d36aeSMartyn Welch of_node_put(cascade_node); 67740d36aeSMartyn Welch } 68740d36aeSMartyn Welch 69740d36aeSMartyn Welch static void __init gef_ppc9a_setup_arch(void) 70740d36aeSMartyn Welch { 71740d36aeSMartyn Welch struct device_node *regs; 72740d36aeSMartyn Welch 73948e78c3SMartyn Welch printk(KERN_INFO "GE Intelligent Platforms PPC9A 6U VME SBC\n"); 74740d36aeSMartyn Welch 75740d36aeSMartyn Welch #ifdef CONFIG_SMP 76740d36aeSMartyn Welch mpc86xx_smp_init(); 77740d36aeSMartyn Welch #endif 78740d36aeSMartyn Welch 79905e75c4SJia Hongtao fsl_pci_assign_primary(); 80905e75c4SJia Hongtao 81740d36aeSMartyn Welch /* Remap basic board registers */ 82740d36aeSMartyn Welch regs = of_find_compatible_node(NULL, NULL, "gef,ppc9a-fpga-regs"); 83740d36aeSMartyn Welch if (regs) { 84740d36aeSMartyn Welch ppc9a_regs = of_iomap(regs, 0); 85740d36aeSMartyn Welch if (ppc9a_regs == NULL) 86740d36aeSMartyn Welch printk(KERN_WARNING "Unable to map board registers\n"); 87740d36aeSMartyn Welch of_node_put(regs); 88740d36aeSMartyn Welch } 893bc26562SMartyn Welch 903bc26562SMartyn Welch #if defined(CONFIG_MMIO_NVRAM) 913bc26562SMartyn Welch mmio_nvram_init(); 923bc26562SMartyn Welch #endif 93740d36aeSMartyn Welch } 94740d36aeSMartyn Welch 95740d36aeSMartyn Welch /* Return the PCB revision */ 96740d36aeSMartyn Welch static unsigned int gef_ppc9a_get_pcb_rev(void) 97740d36aeSMartyn Welch { 98740d36aeSMartyn Welch unsigned int reg; 99740d36aeSMartyn Welch 1002eaa50e9SMartyn Welch reg = ioread32be(ppc9a_regs); 1012eaa50e9SMartyn Welch return (reg >> 16) & 0xff; 102740d36aeSMartyn Welch } 103740d36aeSMartyn Welch 104740d36aeSMartyn Welch /* Return the board (software) revision */ 105740d36aeSMartyn Welch static unsigned int gef_ppc9a_get_board_rev(void) 106740d36aeSMartyn Welch { 107740d36aeSMartyn Welch unsigned int reg; 108740d36aeSMartyn Welch 1092eaa50e9SMartyn Welch reg = ioread32be(ppc9a_regs); 1102eaa50e9SMartyn Welch return (reg >> 8) & 0xff; 111740d36aeSMartyn Welch } 112740d36aeSMartyn Welch 113740d36aeSMartyn Welch /* Return the FPGA revision */ 114740d36aeSMartyn Welch static unsigned int gef_ppc9a_get_fpga_rev(void) 115740d36aeSMartyn Welch { 116740d36aeSMartyn Welch unsigned int reg; 117740d36aeSMartyn Welch 1182eaa50e9SMartyn Welch reg = ioread32be(ppc9a_regs); 1192eaa50e9SMartyn Welch return reg & 0xf; 1202eaa50e9SMartyn Welch } 1212eaa50e9SMartyn Welch 1222eaa50e9SMartyn Welch /* Return VME Geographical Address */ 1232eaa50e9SMartyn Welch static unsigned int gef_ppc9a_get_vme_geo_addr(void) 1242eaa50e9SMartyn Welch { 1252eaa50e9SMartyn Welch unsigned int reg; 1262eaa50e9SMartyn Welch 1272eaa50e9SMartyn Welch reg = ioread32be(ppc9a_regs + 0x4); 1282eaa50e9SMartyn Welch return reg & 0x1f; 1292eaa50e9SMartyn Welch } 1302eaa50e9SMartyn Welch 1312eaa50e9SMartyn Welch /* Return VME System Controller Status */ 1322eaa50e9SMartyn Welch static unsigned int gef_ppc9a_get_vme_is_syscon(void) 1332eaa50e9SMartyn Welch { 1342eaa50e9SMartyn Welch unsigned int reg; 1352eaa50e9SMartyn Welch 1362eaa50e9SMartyn Welch reg = ioread32be(ppc9a_regs + 0x4); 1372eaa50e9SMartyn Welch return (reg >> 9) & 0x1; 138740d36aeSMartyn Welch } 139740d36aeSMartyn Welch 140740d36aeSMartyn Welch static void gef_ppc9a_show_cpuinfo(struct seq_file *m) 141740d36aeSMartyn Welch { 142740d36aeSMartyn Welch uint svid = mfspr(SPRN_SVR); 143740d36aeSMartyn Welch 144948e78c3SMartyn Welch seq_printf(m, "Vendor\t\t: GE Intelligent Platforms\n"); 145740d36aeSMartyn Welch 146740d36aeSMartyn Welch seq_printf(m, "Revision\t: %u%c\n", gef_ppc9a_get_pcb_rev(), 1472eaa50e9SMartyn Welch ('A' + gef_ppc9a_get_board_rev())); 148740d36aeSMartyn Welch seq_printf(m, "FPGA Revision\t: %u\n", gef_ppc9a_get_fpga_rev()); 149740d36aeSMartyn Welch 150740d36aeSMartyn Welch seq_printf(m, "SVR\t\t: 0x%x\n", svid); 1512eaa50e9SMartyn Welch 1522eaa50e9SMartyn Welch seq_printf(m, "VME geo. addr\t: %u\n", gef_ppc9a_get_vme_geo_addr()); 1532eaa50e9SMartyn Welch 1542eaa50e9SMartyn Welch seq_printf(m, "VME syscon\t: %s\n", 1552eaa50e9SMartyn Welch gef_ppc9a_get_vme_is_syscon() ? "yes" : "no"); 156740d36aeSMartyn Welch } 157740d36aeSMartyn Welch 158cad5cef6SGreg Kroah-Hartman static void gef_ppc9a_nec_fixup(struct pci_dev *pdev) 159740d36aeSMartyn Welch { 160740d36aeSMartyn Welch unsigned int val; 161740d36aeSMartyn Welch 162740d36aeSMartyn Welch /* Do not do the fixup on other platforms! */ 163740d36aeSMartyn Welch if (!machine_is(gef_ppc9a)) 164740d36aeSMartyn Welch return; 165740d36aeSMartyn Welch 166740d36aeSMartyn Welch printk(KERN_INFO "Running NEC uPD720101 Fixup\n"); 167740d36aeSMartyn Welch 168740d36aeSMartyn Welch /* Ensure ports 1, 2, 3, 4 & 5 are enabled */ 169740d36aeSMartyn Welch pci_read_config_dword(pdev, 0xe0, &val); 170740d36aeSMartyn Welch pci_write_config_dword(pdev, 0xe0, (val & ~7) | 0x5); 171740d36aeSMartyn Welch 172740d36aeSMartyn Welch /* System clock is 48-MHz Oscillator and EHCI Enabled. */ 173740d36aeSMartyn Welch pci_write_config_dword(pdev, 0xe4, 1 << 5); 174740d36aeSMartyn Welch } 175740d36aeSMartyn Welch DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_USB, 176740d36aeSMartyn Welch gef_ppc9a_nec_fixup); 177740d36aeSMartyn Welch 1784f9d6e95SAlessio Igor Bogani machine_arch_initcall(gef_ppc9a, mpc86xx_common_publish_devices); 179740d36aeSMartyn Welch 180740d36aeSMartyn Welch define_machine(gef_ppc9a) { 181948e78c3SMartyn Welch .name = "GE PPC9A", 1821c96fcdeSChristophe Leroy .compatible = "gef,ppc9a", 183740d36aeSMartyn Welch .setup_arch = gef_ppc9a_setup_arch, 184740d36aeSMartyn Welch .init_IRQ = gef_ppc9a_init_irq, 185740d36aeSMartyn Welch .show_cpuinfo = gef_ppc9a_show_cpuinfo, 186740d36aeSMartyn Welch .get_irq = mpic_get_irq, 187740d36aeSMartyn Welch .time_init = mpc86xx_time_init, 188740d36aeSMartyn Welch .progress = udbg_progress, 189740d36aeSMartyn Welch #ifdef CONFIG_PCI 190740d36aeSMartyn Welch .pcibios_fixup_bus = fsl_pcibios_fixup_bus, 191740d36aeSMartyn Welch #endif 192740d36aeSMartyn Welch }; 193