2009-01-19 14:33:24 +03:00
/*
2010-03-01 17:41:59 +03:00
* GE SBC310 board support
2009-01-19 14:33:24 +03:00
*
2010-03-01 17:41:59 +03:00
* Author : Martyn Welch < martyn . welch @ ge . com >
2009-01-19 14:33:24 +03:00
*
2010-03-01 17:41:59 +03:00
* Copyright 2008 GE Intelligent Platforms Embedded Systems , Inc .
2009-01-19 14:33:24 +03:00
*
* 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 <linux/stddef.h>
# include <linux/kernel.h>
# include <linux/pci.h>
# include <linux/kdev_t.h>
# include <linux/delay.h>
# include <linux/seq_file.h>
# include <linux/of_platform.h>
# include <asm/time.h>
# include <asm/machdep.h>
# include <asm/pci-bridge.h>
# include <asm/prom.h>
# include <mm/mmu_decl.h>
# include <asm/udbg.h>
# include <asm/mpic.h>
2009-07-02 20:12:37 +04:00
# include <asm/nvram.h>
2009-01-19 14:33:24 +03:00
# include <sysdev/fsl_pci.h>
# include <sysdev/fsl_soc.h>
2012-03-12 21:12:59 +04:00
# include <sysdev/ge/ge_pic.h>
2009-01-19 14:33:24 +03:00
# include "mpc86xx.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 ;
2010-03-01 17:41:59 +03:00
printk ( KERN_INFO " GE Intelligent Platforms SBC310 6U VPX SBC \n " ) ;
2009-01-19 14:33:24 +03:00
# ifdef CONFIG_SMP
mpc86xx_smp_init ( ) ;
# endif
2012-08-28 11:44:08 +04:00
fsl_pci_assign_primary ( ) ;
2009-01-19 14:33:24 +03:00
/* 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 ) ;
}
2009-07-02 20:12:37 +04:00
# if defined(CONFIG_MMIO_NVRAM)
mmio_nvram_init ( ) ;
# endif
2009-01-19 14:33:24 +03:00
}
/* 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 ) ;
2010-03-01 17:41:59 +03:00
seq_printf ( m , " Vendor \t \t : GE Intelligent Platforms \n " ) ;
2009-01-19 14:33:24 +03:00
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 ) ;
}
2012-12-22 02:04:10 +04:00
static void gef_sbc310_nec_fixup ( struct pci_dev * pdev )
2009-01-19 14:33:24 +03:00
{
unsigned int val ;
2009-03-13 14:35:08 +03:00
/* Do not do the fixup on other platforms! */
if ( ! machine_is ( gef_sbc310 ) )
return ;
2009-01-19 14:33:24 +03:00
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 ;
}
2016-02-11 17:38:46 +03:00
machine_arch_initcall ( gef_sbc310 , mpc86xx_common_publish_devices ) ;
2009-01-19 14:33:24 +03:00
define_machine ( gef_sbc310 ) {
2010-03-01 17:41:59 +03:00
. name = " GE SBC310 " ,
2009-01-19 14:33:24 +03:00
. 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
} ;