From bb2b66dca1c4cbe16d8208d4b2910cf0eb6e9f75 Mon Sep 17 00:00:00 2001 From: Martyn Welch Date: Mon, 19 Jan 2009 11:33:24 +0000 Subject: powerpc/86xx: Board support for GE Fanuc SBC310 Support for the SBC310 VPX Single Board Computer from GE Fanuc (PowerPC MPC8641D). This is the basic board support for GE Fanuc's SBC310, a 3U single board computer, based on Freescale's MPC8641D. Signed-off-by: Martyn Welch Signed-off-by: Kumar Gala --- arch/powerpc/platforms/86xx/Kconfig | 10 +- arch/powerpc/platforms/86xx/Makefile | 1 + arch/powerpc/platforms/86xx/gef_sbc310.c | 230 +++++++++++++++++++++++++++++++ 3 files changed, 240 insertions(+), 1 deletion(-) create mode 100644 arch/powerpc/platforms/86xx/gef_sbc310.c (limited to 'arch/powerpc/platforms/86xx') diff --git a/arch/powerpc/platforms/86xx/Kconfig b/arch/powerpc/platforms/86xx/Kconfig index 8e56939..fa276c6 100644 --- a/arch/powerpc/platforms/86xx/Kconfig +++ b/arch/powerpc/platforms/86xx/Kconfig @@ -31,6 +31,14 @@ config MPC8610_HPCD help This option enables support for the MPC8610 HPCD board. +config GEF_SBC310 + bool "GE Fanuc SBC310" + select DEFAULT_UIMAGE + select GENERIC_GPIO + select ARCH_REQUIRE_GPIOLIB + help + This option enables support for GE Fanuc's SBC310. + config GEF_SBC610 bool "GE Fanuc SBC610" select DEFAULT_UIMAGE @@ -48,7 +56,7 @@ config MPC8641 select FSL_PCI if PCI select PPC_UDBG_16550 select MPIC - default y if MPC8641_HPCN || SBC8641D || GEF_SBC610 + default y if MPC8641_HPCN || SBC8641D || GEF_SBC610 || GEF_SBC310 config MPC8610 bool diff --git a/arch/powerpc/platforms/86xx/Makefile b/arch/powerpc/platforms/86xx/Makefile index 31e540c..7c080da 100644 --- a/arch/powerpc/platforms/86xx/Makefile +++ b/arch/powerpc/platforms/86xx/Makefile @@ -9,3 +9,4 @@ obj-$(CONFIG_SBC8641D) += sbc8641d.o obj-$(CONFIG_MPC8610_HPCD) += mpc8610_hpcd.o gef-gpio-$(CONFIG_GPIOLIB) += gef_gpio.o obj-$(CONFIG_GEF_SBC610) += gef_sbc610.o gef_pic.o $(gef-gpio-y) +obj-$(CONFIG_GEF_SBC310) += gef_sbc310.o gef_pic.o $(gef-gpio-y) diff --git a/arch/powerpc/platforms/86xx/gef_sbc310.c b/arch/powerpc/platforms/86xx/gef_sbc310.c new file mode 100644 index 0000000..0f20172 --- /dev/null +++ b/arch/powerpc/platforms/86xx/gef_sbc310.c @@ -0,0 +1,230 @@ +/* + * GE Fanuc SBC310 board support + * + * Author: Martyn Welch + * + * Copyright 2008 GE Fanuc Intelligent Platforms Embedded Systems, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * Based on: mpc86xx_hpcn.c (MPC86xx HPCN board specific routines) + * Copyright 2006 Freescale Semiconductor Inc. + * + * NEC fixup adapted from arch/mips/pci/fixup-lm2e.c + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include "mpc86xx.h" +#include "gef_pic.h" + +#undef DEBUG + +#ifdef DEBUG +#define DBG (fmt...) do { printk(KERN_ERR "SBC310: " fmt); } while (0) +#else +#define DBG (fmt...) do { } while (0) +#endif + +void __iomem *sbc310_regs; + +static void __init gef_sbc310_init_irq(void) +{ + struct device_node *cascade_node = NULL; + + mpc86xx_init_irq(); + + /* + * There is a simple interrupt handler in the main FPGA, this needs + * to be cascaded into the MPIC + */ + cascade_node = of_find_compatible_node(NULL, NULL, "gef,fpga-pic"); + if (!cascade_node) { + printk(KERN_WARNING "SBC310: No FPGA PIC\n"); + return; + } + + gef_pic_init(cascade_node); + of_node_put(cascade_node); +} + +static void __init gef_sbc310_setup_arch(void) +{ + struct device_node *regs; +#ifdef CONFIG_PCI + struct device_node *np; + + for_each_compatible_node(np, "pci", "fsl,mpc8641-pcie") { + fsl_add_bridge(np, 1); + } +#endif + + printk(KERN_INFO "GE Fanuc Intelligent Platforms SBC310 6U VPX SBC\n"); + +#ifdef CONFIG_SMP + mpc86xx_smp_init(); +#endif + + /* Remap basic board registers */ + regs = of_find_compatible_node(NULL, NULL, "gef,fpga-regs"); + if (regs) { + sbc310_regs = of_iomap(regs, 0); + if (sbc310_regs == NULL) + printk(KERN_WARNING "Unable to map board registers\n"); + of_node_put(regs); + } +} + +/* Return the PCB revision */ +static unsigned int gef_sbc310_get_board_id(void) +{ + unsigned int reg; + + reg = ioread32(sbc310_regs); + return reg & 0xff; +} + +/* Return the PCB revision */ +static unsigned int gef_sbc310_get_pcb_rev(void) +{ + unsigned int reg; + + reg = ioread32(sbc310_regs); + return (reg >> 8) & 0xff; +} + +/* Return the board (software) revision */ +static unsigned int gef_sbc310_get_board_rev(void) +{ + unsigned int reg; + + reg = ioread32(sbc310_regs); + return (reg >> 16) & 0xff; +} + +/* Return the FPGA revision */ +static unsigned int gef_sbc310_get_fpga_rev(void) +{ + unsigned int reg; + + reg = ioread32(sbc310_regs); + return (reg >> 24) & 0xf; +} + +static void gef_sbc310_show_cpuinfo(struct seq_file *m) +{ + uint svid = mfspr(SPRN_SVR); + + seq_printf(m, "Vendor\t\t: GE Fanuc Intelligent Platforms\n"); + + seq_printf(m, "Board ID\t: 0x%2.2x\n", gef_sbc310_get_board_id()); + seq_printf(m, "Revision\t: %u%c\n", gef_sbc310_get_pcb_rev(), + ('A' + gef_sbc310_get_board_rev() - 1)); + seq_printf(m, "FPGA Revision\t: %u\n", gef_sbc310_get_fpga_rev()); + + seq_printf(m, "SVR\t\t: 0x%x\n", svid); + +} + +static void __init gef_sbc310_nec_fixup(struct pci_dev *pdev) +{ + unsigned int val; + + printk(KERN_INFO "Running NEC uPD720101 Fixup\n"); + + /* Ensure only ports 1 & 2 are enabled */ + pci_read_config_dword(pdev, 0xe0, &val); + pci_write_config_dword(pdev, 0xe0, (val & ~7) | 0x2); + + /* System clock is 48-MHz Oscillator and EHCI Enabled. */ + pci_write_config_dword(pdev, 0xe4, 1 << 5); +} +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_USB, + gef_sbc310_nec_fixup); + +/* + * Called very early, device-tree isn't unflattened + * + * This function is called to determine whether the BSP is compatible with the + * supplied device-tree, which is assumed to be the correct one for the actual + * board. It is expected thati, in the future, a kernel may support multiple + * boards. + */ +static int __init gef_sbc310_probe(void) +{ + unsigned long root = of_get_flat_dt_root(); + + if (of_flat_dt_is_compatible(root, "gef,sbc310")) + return 1; + + return 0; +} + +static long __init mpc86xx_time_init(void) +{ + unsigned int temp; + + /* Set the time base to zero */ + mtspr(SPRN_TBWL, 0); + mtspr(SPRN_TBWU, 0); + + temp = mfspr(SPRN_HID0); + temp |= HID0_TBEN; + mtspr(SPRN_HID0, temp); + asm volatile("isync"); + + return 0; +} + +static __initdata struct of_device_id of_bus_ids[] = { + { .compatible = "simple-bus", }, + {}, +}; + +static int __init declare_of_platform_devices(void) +{ + printk(KERN_DEBUG "Probe platform devices\n"); + of_platform_bus_probe(NULL, of_bus_ids, NULL); + + return 0; +} +machine_device_initcall(gef_sbc310, declare_of_platform_devices); + +define_machine(gef_sbc310) { + .name = "GE Fanuc SBC310", + .probe = gef_sbc310_probe, + .setup_arch = gef_sbc310_setup_arch, + .init_IRQ = gef_sbc310_init_irq, + .show_cpuinfo = gef_sbc310_show_cpuinfo, + .get_irq = mpic_get_irq, + .restart = fsl_rstcr_restart, + .time_init = mpc86xx_time_init, + .calibrate_decr = generic_calibrate_decr, + .progress = udbg_progress, +#ifdef CONFIG_PCI + .pcibios_fixup_bus = fsl_pcibios_fixup_bus, +#endif +}; -- cgit v1.1