2019-05-27 08:55:01 +02:00
// SPDX-License-Identifier: GPL-2.0-or-later
2009-03-19 08:54:08 +00:00
/*
2010-03-01 14:41:59 +00:00
* GE PPC9A board support
2009-03-19 08:54:08 +00:00
*
2010-03-01 14:41:59 +00:00
* Author : Martyn Welch < martyn . welch @ ge . com >
2009-03-19 08:54:08 +00:00
*
2010-03-01 14:41:59 +00:00
* Copyright 2008 GE Intelligent Platforms Embedded Systems , Inc .
2009-03-19 08:54:08 +00:00
*
* 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>
2022-03-08 20:20:25 +01:00
# include <linux/of_address.h>
2009-03-19 08:54:08 +00:00
# include <linux/of_platform.h>
# include <asm/time.h>
# include <asm/machdep.h>
# include <asm/pci-bridge.h>
# include <mm/mmu_decl.h>
# include <asm/udbg.h>
# include <asm/mpic.h>
2009-07-02 17:12:44 +01:00
# include <asm/nvram.h>
2009-03-19 08:54:08 +00:00
# include <sysdev/fsl_pci.h>
# include <sysdev/fsl_soc.h>
2012-03-12 17:12:59 +00:00
# include <sysdev/ge/ge_pic.h>
2009-03-19 08:54:08 +00:00
# include "mpc86xx.h"
# undef DEBUG
# ifdef DEBUG
# define DBG (fmt...) do { printk(KERN_ERR "PPC9A: " fmt); } while (0)
# else
# define DBG (fmt...) do { } while (0)
# endif
void __iomem * ppc9a_regs ;
static void __init gef_ppc9a_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-1.00 " ) ;
if ( ! cascade_node ) {
printk ( KERN_WARNING " PPC9A: No FPGA PIC \n " ) ;
return ;
}
gef_pic_init ( cascade_node ) ;
of_node_put ( cascade_node ) ;
}
static void __init gef_ppc9a_setup_arch ( void )
{
struct device_node * regs ;
2010-03-01 14:41:59 +00:00
printk ( KERN_INFO " GE Intelligent Platforms PPC9A 6U VME SBC \n " ) ;
2009-03-19 08:54:08 +00:00
# ifdef CONFIG_SMP
mpc86xx_smp_init ( ) ;
# endif
2012-08-28 15:44:08 +08:00
fsl_pci_assign_primary ( ) ;
2009-03-19 08:54:08 +00:00
/* Remap basic board registers */
regs = of_find_compatible_node ( NULL , NULL , " gef,ppc9a-fpga-regs " ) ;
if ( regs ) {
ppc9a_regs = of_iomap ( regs , 0 ) ;
if ( ppc9a_regs = = NULL )
printk ( KERN_WARNING " Unable to map board registers \n " ) ;
of_node_put ( regs ) ;
}
2009-07-02 17:12:44 +01:00
# if defined(CONFIG_MMIO_NVRAM)
mmio_nvram_init ( ) ;
# endif
2009-03-19 08:54:08 +00:00
}
/* Return the PCB revision */
static unsigned int gef_ppc9a_get_pcb_rev ( void )
{
unsigned int reg ;
2009-06-30 15:32:26 +01:00
reg = ioread32be ( ppc9a_regs ) ;
return ( reg > > 16 ) & 0xff ;
2009-03-19 08:54:08 +00:00
}
/* Return the board (software) revision */
static unsigned int gef_ppc9a_get_board_rev ( void )
{
unsigned int reg ;
2009-06-30 15:32:26 +01:00
reg = ioread32be ( ppc9a_regs ) ;
return ( reg > > 8 ) & 0xff ;
2009-03-19 08:54:08 +00:00
}
/* Return the FPGA revision */
static unsigned int gef_ppc9a_get_fpga_rev ( void )
{
unsigned int reg ;
2009-06-30 15:32:26 +01:00
reg = ioread32be ( ppc9a_regs ) ;
return reg & 0xf ;
}
/* Return VME Geographical Address */
static unsigned int gef_ppc9a_get_vme_geo_addr ( void )
{
unsigned int reg ;
reg = ioread32be ( ppc9a_regs + 0x4 ) ;
return reg & 0x1f ;
}
/* Return VME System Controller Status */
static unsigned int gef_ppc9a_get_vme_is_syscon ( void )
{
unsigned int reg ;
reg = ioread32be ( ppc9a_regs + 0x4 ) ;
return ( reg > > 9 ) & 0x1 ;
2009-03-19 08:54:08 +00:00
}
static void gef_ppc9a_show_cpuinfo ( struct seq_file * m )
{
uint svid = mfspr ( SPRN_SVR ) ;
2010-03-01 14:41:59 +00:00
seq_printf ( m , " Vendor \t \t : GE Intelligent Platforms \n " ) ;
2009-03-19 08:54:08 +00:00
seq_printf ( m , " Revision \t : %u%c \n " , gef_ppc9a_get_pcb_rev ( ) ,
2009-06-30 15:32:26 +01:00
( ' A ' + gef_ppc9a_get_board_rev ( ) ) ) ;
2009-03-19 08:54:08 +00:00
seq_printf ( m , " FPGA Revision \t : %u \n " , gef_ppc9a_get_fpga_rev ( ) ) ;
seq_printf ( m , " SVR \t \t : 0x%x \n " , svid ) ;
2009-06-30 15:32:26 +01:00
seq_printf ( m , " VME geo. addr \t : %u \n " , gef_ppc9a_get_vme_geo_addr ( ) ) ;
seq_printf ( m , " VME syscon \t : %s \n " ,
gef_ppc9a_get_vme_is_syscon ( ) ? " yes " : " no " ) ;
2009-03-19 08:54:08 +00:00
}
2012-12-21 14:04:10 -08:00
static void gef_ppc9a_nec_fixup ( struct pci_dev * pdev )
2009-03-19 08:54:08 +00:00
{
unsigned int val ;
/* Do not do the fixup on other platforms! */
if ( ! machine_is ( gef_ppc9a ) )
return ;
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_ppc9a_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
2022-04-30 20:56:54 +02:00
* board . It is expected that , in the future , a kernel may support multiple
2009-03-19 08:54:08 +00:00
* boards .
*/
static int __init gef_ppc9a_probe ( void )
{
2016-07-05 15:04:05 +10:00
if ( of_machine_is_compatible ( " gef,ppc9a " ) )
2009-03-19 08:54:08 +00:00
return 1 ;
return 0 ;
}
2016-02-11 15:38:46 +01:00
machine_arch_initcall ( gef_ppc9a , mpc86xx_common_publish_devices ) ;
2009-03-19 08:54:08 +00:00
define_machine ( gef_ppc9a ) {
2010-03-01 14:41:59 +00:00
. name = " GE PPC9A " ,
2009-03-19 08:54:08 +00:00
. probe = gef_ppc9a_probe ,
. setup_arch = gef_ppc9a_setup_arch ,
. init_IRQ = gef_ppc9a_init_irq ,
. show_cpuinfo = gef_ppc9a_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
} ;