2008-09-01 17:22:39 +04:00
/*
* Based on linux / arch / mips / txx9 / rbtx4939 / setup . c ,
* and RBTX49xx patch from CELF patch archive .
*
* Copyright 2001 , 2003 - 2005 MontaVista Software Inc .
* Copyright ( C ) 2004 by Ralf Baechle ( ralf @ linux - mips . org )
* ( C ) Copyright TOSHIBA CORPORATION 2000 - 2001 , 2004 - 2007
*
* This file is subject to the terms and conditions of the GNU General Public
* License . See the file " COPYING " in the main directory of this archive
* for more details .
*/
# include <linux/init.h>
# include <linux/pci.h>
# include <linux/kernel.h>
# include <linux/interrupt.h>
# include <asm/txx9/generic.h>
# include <asm/txx9/tx4939.h>
int __init tx4939_report_pciclk ( void )
{
int pciclk = 0 ;
pr_info ( " PCIC --%s PCICLK: " ,
( __raw_readq ( & tx4939_ccfgptr - > ccfg ) & TX4939_CCFG_PCI66 ) ?
" PCI66 " : " " ) ;
if ( __raw_readq ( & tx4939_ccfgptr - > pcfg ) & TX4939_PCFG_PCICLKEN_ALL ) {
pciclk = txx9_master_clock * 20 / 6 ;
if ( ! ( __raw_readq ( & tx4939_ccfgptr - > ccfg ) & TX4939_CCFG_PCI66 ) )
pciclk / = 2 ;
printk ( KERN_CONT " Internal(%u.%uMHz) " ,
( pciclk + 50000 ) / 1000000 ,
( ( pciclk + 50000 ) / 100000 ) % 10 ) ;
} else {
printk ( KERN_CONT " External " ) ;
pciclk = - 1 ;
}
printk ( KERN_CONT " \n " ) ;
return pciclk ;
}
void __init tx4939_report_pci1clk ( void )
{
unsigned int pciclk = txx9_master_clock * 20 / 6 ;
pr_info ( " PCIC1 -- PCICLK:%u.%uMHz \n " ,
( pciclk + 50000 ) / 1000000 ,
( ( pciclk + 50000 ) / 100000 ) % 10 ) ;
}
int __init tx4939_pcic1_map_irq ( const struct pci_dev * dev , u8 slot )
{
if ( get_tx4927_pcicptr ( dev - > bus - > sysdata ) = = tx4939_pcic1ptr ) {
switch ( slot ) {
case TX4927_PCIC_IDSEL_AD_TO_SLOT ( 31 ) :
if ( __raw_readq ( & tx4939_ccfgptr - > pcfg ) &
TX4939_PCFG_ET0MODE )
return TXX9_IRQ_BASE + TX4939_IR_ETH ( 0 ) ;
break ;
case TX4927_PCIC_IDSEL_AD_TO_SLOT ( 30 ) :
if ( __raw_readq ( & tx4939_ccfgptr - > pcfg ) &
TX4939_PCFG_ET1MODE )
return TXX9_IRQ_BASE + TX4939_IR_ETH ( 1 ) ;
break ;
}
return 0 ;
}
return - 1 ;
}
int __init tx4939_pci_map_irq ( const struct pci_dev * dev , u8 slot , u8 pin )
{
int irq = tx4939_pcic1_map_irq ( dev , slot ) ;
if ( irq > = 0 )
return irq ;
irq = pin ;
/* IRQ rotation */
irq - - ; /* 0-3 */
irq = ( irq + 33 - slot ) % 4 ;
irq + + ; /* 1-4 */
switch ( irq ) {
case 1 :
irq = TXX9_IRQ_BASE + TX4939_IR_INTA ;
break ;
case 2 :
irq = TXX9_IRQ_BASE + TX4939_IR_INTB ;
break ;
case 3 :
irq = TXX9_IRQ_BASE + TX4939_IR_INTC ;
break ;
case 4 :
irq = TXX9_IRQ_BASE + TX4939_IR_INTD ;
break ;
}
return irq ;
}
void __init tx4939_setup_pcierr_irq ( void )
{
if ( request_irq ( TXX9_IRQ_BASE + TX4939_IR_PCIERR ,
tx4927_pcierr_interrupt ,
2011-11-22 18:38:03 +04:00
0 , " PCI error " ,
2008-09-01 17:22:39 +04:00
( void * ) TX4939_PCIC_REG ) )
pr_warning ( " Failed to request irq for PCIERR \n " ) ;
}