2005-04-16 15:20:36 -07:00
/*
* arch / arm / mach - ixp2000 / ixdp2400 . c
*
* IXDP2400 platform support
*
* Original Author : Naeem Afzal < naeem . m . afzal @ intel . com >
* Maintainer : Deepak Saxena < dsaxena @ plexity . net >
*
* Copyright ( C ) 2002 Intel Corp .
* Copyright ( C ) 2003 - 2004 MontaVista Software , 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 .
*/
# include <linux/kernel.h>
# include <linux/init.h>
# include <linux/mm.h>
# include <linux/sched.h>
# include <linux/interrupt.h>
# include <linux/device.h>
# include <linux/bitops.h>
# include <linux/pci.h>
# include <linux/ioport.h>
# include <linux/slab.h>
# include <linux/delay.h>
2008-09-06 12:10:45 +01:00
# include <linux/io.h>
2005-04-16 15:20:36 -07:00
# include <asm/irq.h>
# include <asm/pgtable.h>
# include <asm/page.h>
# include <asm/system.h>
2008-08-05 16:14:15 +01:00
# include <mach/hardware.h>
2005-04-16 15:20:36 -07:00
# include <asm/mach-types.h>
# include <asm/mach/pci.h>
# include <asm/mach/map.h>
# include <asm/mach/irq.h>
# include <asm/mach/time.h>
# include <asm/mach/flash.h>
# include <asm/mach/arch.h>
/*************************************************************************
* IXDP2400 timer tick
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void __init ixdp2400_timer_init ( void )
{
int numerator , denominator ;
int denom_array [ ] = { 2 , 4 , 8 , 16 , 1 , 2 , 4 , 8 } ;
numerator = ( * ( IXDP2400_CPLD_SYS_CLK_M ) & 0xFF ) * 2 ;
denominator = denom_array [ ( * ( IXDP2400_CPLD_SYS_CLK_N ) & 0x7 ) ] ;
ixp2000_init_time ( ( ( 3125000 * numerator ) / ( denominator ) ) / 2 ) ;
}
static struct sys_timer ixdp2400_timer = {
. init = ixdp2400_timer_init ,
. offset = ixp2000_gettimeoffset ,
} ;
/*************************************************************************
* IXDP2400 PCI
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void __init ixdp2400_pci_preinit ( void )
{
ixp2000_reg_write ( IXP2000_PCI_ADDR_EXT , 0x00100000 ) ;
ixp2000_pci_preinit ( ) ;
2006-02-08 21:09:04 +00:00
pcibios_setup ( " firmware " ) ;
2005-04-16 15:20:36 -07:00
}
int ixdp2400_pci_setup ( int nr , struct pci_sys_data * sys )
{
sys - > mem_offset = 0xe0000000 ;
ixp2000_pci_setup ( nr , sys ) ;
return 1 ;
}
static int __init ixdp2400_pci_map_irq ( struct pci_dev * dev , u8 slot , u8 pin )
{
if ( ixdp2x00_master_npu ( ) ) {
/*
* Root bus devices . Slave NPU is only one with interrupt .
* Everything else , we just return - 1 b / c nothing else
* on the root bus has interrupts .
*/
if ( ! dev - > bus - > self ) {
if ( dev - > devfn = = IXDP2X00_SLAVE_NPU_DEVFN )
return IRQ_IXDP2400_INGRESS_NPU ;
return - 1 ;
}
/*
* Bridge behind the PMC slot .
* NOTE : Only INTA from the PMC slot is routed . VERY BAD .
*/
if ( dev - > bus - > self - > devfn = = IXDP2X00_PMC_DEVFN & &
dev - > bus - > parent - > self - > devfn = = IXDP2X00_P2P_DEVFN & &
! dev - > bus - > parent - > self - > bus - > parent )
return IRQ_IXDP2400_PMC ;
/*
* Device behind the first bridge
*/
if ( dev - > bus - > self - > devfn = = IXDP2X00_P2P_DEVFN ) {
switch ( dev - > devfn ) {
case IXDP2400_MASTER_ENET_DEVFN :
return IRQ_IXDP2400_ENET ;
case IXDP2400_MEDIA_DEVFN :
return IRQ_IXDP2400_MEDIA_PCI ;
case IXDP2400_SWITCH_FABRIC_DEVFN :
return IRQ_IXDP2400_SF_PCI ;
case IXDP2X00_PMC_DEVFN :
return IRQ_IXDP2400_PMC ;
}
}
return - 1 ;
} else return IRQ_IXP2000_PCIB ; /* Slave NIC interrupt */
}
static void ixdp2400_pci_postinit ( void )
{
struct pci_dev * dev ;
if ( ixdp2x00_master_npu ( ) ) {
2006-10-16 16:49:50 +01:00
dev = pci_get_bus_and_slot ( 1 , IXDP2400_SLAVE_ENET_DEVFN ) ;
2005-04-16 15:20:36 -07:00
pci_remove_bus_device ( dev ) ;
2006-10-20 20:16:24 +01:00
pci_dev_put ( dev ) ;
2005-04-16 15:20:36 -07:00
} else {
2006-10-16 16:49:50 +01:00
dev = pci_get_bus_and_slot ( 1 , IXDP2400_MASTER_ENET_DEVFN ) ;
2005-04-16 15:20:36 -07:00
pci_remove_bus_device ( dev ) ;
2006-10-20 20:16:24 +01:00
pci_dev_put ( dev ) ;
2005-04-16 15:20:36 -07:00
ixdp2x00_slave_pci_postinit ( ) ;
}
}
static struct hw_pci ixdp2400_pci __initdata = {
. nr_controllers = 1 ,
. setup = ixdp2400_pci_setup ,
. preinit = ixdp2400_pci_preinit ,
. postinit = ixdp2400_pci_postinit ,
. scan = ixp2000_pci_scan_bus ,
. map_irq = ixdp2400_pci_map_irq ,
} ;
int __init ixdp2400_pci_init ( void )
{
if ( machine_is_ixdp2400 ( ) )
pci_common_init ( & ixdp2400_pci ) ;
return 0 ;
}
subsys_initcall ( ixdp2400_pci_init ) ;
2007-05-30 17:48:45 +01:00
void __init ixdp2400_init_irq ( void )
2005-04-16 15:20:36 -07:00
{
ixdp2x00_init_irq ( IXDP2400_CPLD_INT_STAT , IXDP2400_CPLD_INT_MASK , IXDP2400_NR_IRQS ) ;
}
MACHINE_START ( IXDP2400 , " Intel IXDP2400 Development Platform " )
2005-07-03 17:38:58 +01:00
/* Maintainer: MontaVista Software, Inc. */
. phys_io = IXP2000_UART_PHYS_BASE ,
. io_pg_offst = ( ( IXP2000_UART_VIRT_BASE ) > > 18 ) & 0xfffc ,
. boot_params = 0x00000100 ,
. map_io = ixdp2x00_map_io ,
. init_irq = ixdp2400_init_irq ,
2005-04-16 15:20:36 -07:00
. timer = & ixdp2400_timer ,
2005-07-03 17:38:58 +01:00
. init_machine = ixdp2x00_init_machine ,
2005-04-16 15:20:36 -07:00
MACHINE_END