2019-05-27 09:55:01 +03:00
// SPDX-License-Identifier: GPL-2.0-or-later
2008-09-16 13:57:47 +04:00
/*
2010-03-01 17:41:59 +03:00
* GE SBC610 board support
2008-09-16 13:57:47 +04:00
*
2010-03-01 17:41:59 +03:00
* Author : Martyn Welch < martyn . welch @ ge . com >
2008-09-16 13:57:47 +04:00
*
2010-03-01 17:41:59 +03:00
* Copyright 2008 GE Intelligent Platforms Embedded Systems , Inc .
2008-09-16 13:57:47 +04:00
*
* Based on : mpc86xx_hpcn . c ( MPC86xx HPCN board specific routines )
* Copyright 2006 Freescale Semiconductor Inc .
2008-09-29 16:35:15 +04:00
*
* NEC fixup adapted from arch / mips / pci / fixup - lm2e . c
2008-09-16 13:57:47 +04:00
*/
# 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:31 +04:00
# include <asm/nvram.h>
2008-09-16 13:57:47 +04: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>
2008-09-16 13:57:47 +04:00
# include "mpc86xx.h"
# undef DEBUG
# ifdef DEBUG
# define DBG (fmt...) do { printk(KERN_ERR "SBC610: " fmt); } while (0)
# else
# define DBG (fmt...) do { } while (0)
# endif
2008-10-01 12:32:39 +04:00
void __iomem * sbc610_regs ;
static void __init gef_sbc610_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 " SBC610: No FPGA PIC \n " ) ;
return ;
}
gef_pic_init ( cascade_node ) ;
of_node_put ( cascade_node ) ;
}
2008-09-16 13:57:47 +04:00
static void __init gef_sbc610_setup_arch ( void )
{
2008-10-13 19:16:45 +04:00
struct device_node * regs ;
2008-09-16 13:57:47 +04:00
2010-03-01 17:41:59 +03:00
printk ( KERN_INFO " GE Intelligent Platforms SBC610 6U VPX SBC \n " ) ;
2008-09-16 13:57:47 +04:00
# ifdef CONFIG_SMP
mpc86xx_smp_init ( ) ;
# endif
2008-10-13 19:16:45 +04:00
2012-08-28 11:44:08 +04:00
fsl_pci_assign_primary ( ) ;
2008-10-13 19:16:45 +04:00
/* Remap basic board registers */
regs = of_find_compatible_node ( NULL , NULL , " gef,fpga-regs " ) ;
if ( regs ) {
sbc610_regs = of_iomap ( regs , 0 ) ;
if ( sbc610_regs = = NULL )
printk ( KERN_WARNING " Unable to map board registers \n " ) ;
of_node_put ( regs ) ;
}
2009-07-02 20:12:31 +04:00
# if defined(CONFIG_MMIO_NVRAM)
mmio_nvram_init ( ) ;
# endif
2008-10-13 19:16:45 +04:00
}
/* Return the PCB revision */
static unsigned int gef_sbc610_get_pcb_rev ( void )
{
unsigned int reg ;
reg = ioread32 ( sbc610_regs ) ;
return ( reg > > 8 ) & 0xff ;
}
/* Return the board (software) revision */
static unsigned int gef_sbc610_get_board_rev ( void )
{
unsigned int reg ;
reg = ioread32 ( sbc610_regs ) ;
return ( reg > > 16 ) & 0xff ;
2008-09-16 13:57:47 +04:00
}
2008-10-13 19:16:45 +04:00
/* Return the FPGA revision */
static unsigned int gef_sbc610_get_fpga_rev ( void )
{
unsigned int reg ;
reg = ioread32 ( sbc610_regs ) ;
return ( reg > > 24 ) & 0xf ;
}
2008-09-16 13:57:47 +04:00
static void gef_sbc610_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 " ) ;
2008-09-16 13:57:47 +04:00
2008-10-13 19:16:45 +04:00
seq_printf ( m , " Revision \t : %u%c \n " , gef_sbc610_get_pcb_rev ( ) ,
( ' A ' + gef_sbc610_get_board_rev ( ) - 1 ) ) ;
seq_printf ( m , " FPGA Revision \t : %u \n " , gef_sbc610_get_fpga_rev ( ) ) ;
2008-09-16 13:57:47 +04:00
seq_printf ( m , " SVR \t \t : 0x%x \n " , svid ) ;
}
2012-12-22 02:04:10 +04:00
static void gef_sbc610_nec_fixup ( struct pci_dev * pdev )
2008-09-29 16:35:15 +04:00
{
unsigned int val ;
2009-03-03 20:59:30 +03:00
/* Do not do the fixup on other platforms! */
if ( ! machine_is ( gef_sbc610 ) )
return ;
2008-09-29 16:35:15 +04:00
printk ( KERN_INFO " Running NEC uPD720101 Fixup \n " ) ;
/* Ensure ports 1, 2, 3, 4 & 5 are enabled */
pci_read_config_dword ( pdev , 0xe0 , & val ) ;
pci_write_config_dword ( pdev , 0xe0 , ( val & ~ 7 ) | 0x5 ) ;
/* 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_sbc610_nec_fixup ) ;
2008-09-16 13:57:47 +04:00
/*
* 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_sbc610_probe ( void )
{
2016-07-05 08:04:05 +03:00
if ( of_machine_is_compatible ( " gef,sbc610 " ) )
2008-09-16 13:57:47 +04:00
return 1 ;
return 0 ;
}
2016-02-11 17:38:46 +03:00
machine_arch_initcall ( gef_sbc610 , mpc86xx_common_publish_devices ) ;
2008-09-16 13:57:47 +04:00
define_machine ( gef_sbc610 ) {
2010-03-01 17:41:59 +03:00
. name = " GE SBC610 " ,
2008-09-16 13:57:47 +04:00
. probe = gef_sbc610_probe ,
. setup_arch = gef_sbc610_setup_arch ,
2008-10-01 12:32:39 +04:00
. init_IRQ = gef_sbc610_init_irq ,
2008-09-16 13:57:47 +04:00
. show_cpuinfo = gef_sbc610_show_cpuinfo ,
. get_irq = mpic_get_irq ,
. time_init = mpc86xx_time_init ,
. calibrate_decr = generic_calibrate_decr ,
. progress = udbg_progress ,
# ifdef CONFIG_PCI
. pcibios_fixup_bus = fsl_pcibios_fixup_bus ,
# endif
} ;