2005-04-17 02:20:36 +04:00
/*
* Cobalt Qube / Raq PCI support
*
* 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 .
*
* Copyright ( C ) 1995 , 1996 , 1997 , 2002 , 2003 by Ralf Baechle
* Copyright ( C ) 2001 , 2002 , 2003 by Liam Davies ( ldavies @ agile . tv )
*/
# include <linux/types.h>
# include <linux/pci.h>
# include <linux/kernel.h>
# include <linux/init.h>
# include <asm/pci.h>
# include <asm/io.h>
# include <asm/gt64120.h>
2007-05-10 15:00:55 +04:00
# include <cobalt.h>
2007-09-13 18:51:26 +04:00
# include <irq.h>
2005-04-17 02:20:36 +04:00
2007-10-02 17:54:41 +04:00
/*
* PCI slot numbers
*/
# define COBALT_PCICONF_CPU 0x06
# define COBALT_PCICONF_ETH0 0x07
# define COBALT_PCICONF_RAQSCSI 0x08
# define COBALT_PCICONF_VIA 0x09
# define COBALT_PCICONF_PCISLOT 0x0A
# define COBALT_PCICONF_ETH1 0x0C
/*
* The Cobalt board ID information . The boards have an ID number wired
* into the VIA that is available in the high nibble of register 94.
*/
# define VIA_COBALT_BRD_ID_REG 0x94
# define VIA_COBALT_BRD_REG_to_ID(reg) ((unsigned char)(reg) >> 4)
2012-12-22 02:04:39 +04:00
static void qube_raq_galileo_early_fixup ( struct pci_dev * dev )
2005-02-21 19:18:36 +03:00
{
if ( dev - > devfn = = PCI_DEVFN ( 0 , 0 ) & &
( dev - > class > > 8 ) = = PCI_CLASS_MEMORY_OTHER ) {
dev - > class = ( PCI_CLASS_BRIDGE_HOST < < 8 ) | ( dev - > class & 0xff ) ;
printk ( KERN_INFO " Galileo: fixed bridge class \n " ) ;
}
}
DECLARE_PCI_FIXUP_EARLY ( PCI_VENDOR_ID_MARVELL , PCI_DEVICE_ID_MARVELL_GT64111 ,
qube_raq_galileo_early_fixup ) ;
2012-12-22 02:04:39 +04:00
static void qube_raq_via_bmIDE_fixup ( struct pci_dev * dev )
2005-04-17 02:20:36 +04:00
{
unsigned short cfgword ;
unsigned char lt ;
/* Enable Bus Mastering and fast back to back. */
pci_read_config_word ( dev , PCI_COMMAND , & cfgword ) ;
cfgword | = ( PCI_COMMAND_FAST_BACK | PCI_COMMAND_MASTER ) ;
pci_write_config_word ( dev , PCI_COMMAND , cfgword ) ;
/* Enable both ide interfaces. ROM only enables primary one. */
pci_write_config_byte ( dev , 0x40 , 0xb ) ;
/* Set latency timer to reasonable value. */
pci_read_config_byte ( dev , PCI_LATENCY_TIMER , & lt ) ;
if ( lt < 64 )
pci_write_config_byte ( dev , PCI_LATENCY_TIMER , 64 ) ;
2006-01-30 00:33:48 +03:00
pci_write_config_byte ( dev , PCI_CACHE_LINE_SIZE , 8 ) ;
2005-04-17 02:20:36 +04:00
}
DECLARE_PCI_FIXUP_HEADER ( PCI_VENDOR_ID_VIA , PCI_DEVICE_ID_VIA_82C586_1 ,
qube_raq_via_bmIDE_fixup ) ;
2012-12-22 02:04:39 +04:00
static void qube_raq_galileo_fixup ( struct pci_dev * dev )
2005-04-17 02:20:36 +04:00
{
2005-02-21 19:18:36 +03:00
if ( dev - > devfn ! = PCI_DEVFN ( 0 , 0 ) )
return ;
2005-04-17 02:20:36 +04:00
/* Fix PCI latency-timer and cache-line-size values in Galileo
* host bridge .
*/
pci_write_config_byte ( dev , PCI_LATENCY_TIMER , 64 ) ;
2006-01-30 00:33:48 +03:00
pci_write_config_byte ( dev , PCI_CACHE_LINE_SIZE , 8 ) ;
2005-04-17 02:20:36 +04:00
/*
2005-02-21 19:18:36 +03:00
* The code described by the comment below has been removed
* as it causes bus mastering by the Ethernet controllers
* to break under any kind of network load . We always set
* the retry timeouts to their maximum .
*
* - - x - - x - - x - - x - - x - - x - - x - - x - - x - - x - - x - - x - - x - - x - - x - - x - - x - - x - - x - - x - -
*
2005-04-17 02:20:36 +04:00
* On all machines prior to Q2 , we had the STOP line disconnected
2013-01-22 15:59:30 +04:00
* from Galileo to VIA on PCI . The new Galileo does not function
2005-04-17 02:20:36 +04:00
* correctly unless we have it connected .
*
* Therefore we must set the disconnect / retry cycle values to
* something sensible when using the new Galileo .
*/
2005-02-21 19:18:36 +03:00
2013-01-22 15:59:30 +04:00
printk ( KERN_INFO " Galileo: revision %u \n " , dev - > revision ) ;
2005-02-21 19:18:36 +03:00
#if 0
2007-06-09 02:46:36 +04:00
if ( dev - > revision > = 0x10 ) {
2005-04-17 02:20:36 +04:00
/* New Galileo, assumes PCI stop line to VIA is connected. */
2006-10-13 19:25:04 +04:00
GT_WRITE ( GT_PCI0_TOR_OFS , 0x4020 ) ;
2007-06-09 02:46:36 +04:00
} else if ( dev - > revision = = 0x1 | | dev - > revision = = 0x2 )
2005-02-21 19:18:36 +03:00
# endif
{
2005-04-17 02:20:36 +04:00
signed int timeo ;
/* XXX WE MUST DO THIS ELSE GALILEO LOCKS UP! -DaveM */
2006-10-13 19:25:04 +04:00
timeo = GT_READ ( GT_PCI0_TOR_OFS ) ;
2005-04-17 02:20:36 +04:00
/* Old Galileo, assumes PCI STOP line to VIA is disconnected. */
2006-10-13 19:25:04 +04:00
GT_WRITE ( GT_PCI0_TOR_OFS ,
2005-02-21 19:18:36 +03:00
( 0xff < < 16 ) | /* retry count */
( 0xff < < 8 ) | /* timeout 1 */
2006-10-13 19:25:04 +04:00
0xff ) ; /* timeout 0 */
2005-02-21 19:18:36 +03:00
/* enable PCI retry exceeded interrupt */
2006-10-13 19:25:04 +04:00
GT_WRITE ( GT_INTRMASK_OFS , GT_INTR_RETRYCTR0_MSK | GT_READ ( GT_INTRMASK_OFS ) ) ;
2005-04-17 02:20:36 +04:00
}
}
2005-02-21 19:18:36 +03:00
DECLARE_PCI_FIXUP_HEADER ( PCI_VENDOR_ID_MARVELL , PCI_DEVICE_ID_MARVELL_GT64111 ,
2005-04-17 02:20:36 +04:00
qube_raq_galileo_fixup ) ;
2007-05-11 16:43:09 +04:00
int cobalt_board_id ;
2012-12-22 02:04:39 +04:00
static void qube_raq_via_board_id_fixup ( struct pci_dev * dev )
2007-05-11 16:43:09 +04:00
{
u8 id ;
int retval ;
retval = pci_read_config_byte ( dev , VIA_COBALT_BRD_ID_REG , & id ) ;
if ( retval ) {
panic ( " Cannot read board ID " ) ;
return ;
}
cobalt_board_id = VIA_COBALT_BRD_REG_to_ID ( id ) ;
printk ( KERN_INFO " Cobalt board ID: %d \n " , cobalt_board_id ) ;
}
DECLARE_PCI_FIXUP_HEADER ( PCI_VENDOR_ID_VIA , PCI_DEVICE_ID_VIA_82C586_0 ,
qube_raq_via_board_id_fixup ) ;
2005-02-21 19:18:36 +03:00
static char irq_tab_qube1 [ ] __initdata = {
2013-01-22 15:59:30 +04:00
[ COBALT_PCICONF_CPU ] = 0 ,
[ COBALT_PCICONF_ETH0 ] = QUBE1_ETH0_IRQ ,
2007-09-13 18:51:26 +04:00
[ COBALT_PCICONF_RAQSCSI ] = SCSI_IRQ ,
2013-01-22 15:59:30 +04:00
[ COBALT_PCICONF_VIA ] = 0 ,
2007-09-13 18:51:26 +04:00
[ COBALT_PCICONF_PCISLOT ] = PCISLOT_IRQ ,
2013-01-22 15:59:30 +04:00
[ COBALT_PCICONF_ETH1 ] = 0
2005-02-21 19:18:36 +03:00
} ;
2005-04-17 02:20:36 +04:00
static char irq_tab_cobalt [ ] __initdata = {
2013-01-22 15:59:30 +04:00
[ COBALT_PCICONF_CPU ] = 0 ,
[ COBALT_PCICONF_ETH0 ] = ETH0_IRQ ,
2007-09-13 18:51:26 +04:00
[ COBALT_PCICONF_RAQSCSI ] = SCSI_IRQ ,
2013-01-22 15:59:30 +04:00
[ COBALT_PCICONF_VIA ] = 0 ,
2007-09-13 18:51:26 +04:00
[ COBALT_PCICONF_PCISLOT ] = PCISLOT_IRQ ,
2013-01-22 15:59:30 +04:00
[ COBALT_PCICONF_ETH1 ] = ETH1_IRQ
2005-04-17 02:20:36 +04:00
} ;
static char irq_tab_raq2 [ ] __initdata = {
2013-01-22 15:59:30 +04:00
[ COBALT_PCICONF_CPU ] = 0 ,
[ COBALT_PCICONF_ETH0 ] = ETH0_IRQ ,
2007-09-13 18:51:26 +04:00
[ COBALT_PCICONF_RAQSCSI ] = RAQ2_SCSI_IRQ ,
2013-01-22 15:59:30 +04:00
[ COBALT_PCICONF_VIA ] = 0 ,
2007-09-13 18:51:26 +04:00
[ COBALT_PCICONF_PCISLOT ] = PCISLOT_IRQ ,
2013-01-22 15:59:30 +04:00
[ COBALT_PCICONF_ETH1 ] = ETH1_IRQ
2005-04-17 02:20:36 +04:00
} ;
2007-07-10 20:33:00 +04:00
int __init pcibios_map_irq ( const struct pci_dev * dev , u8 slot , u8 pin )
2005-04-17 02:20:36 +04:00
{
2008-01-12 02:25:14 +03:00
if ( cobalt_board_id < = COBALT_BRD_ID_QUBE1 )
2005-02-21 19:18:36 +03:00
return irq_tab_qube1 [ slot ] ;
2005-04-17 02:20:36 +04:00
if ( cobalt_board_id = = COBALT_BRD_ID_RAQ2 )
return irq_tab_raq2 [ slot ] ;
return irq_tab_cobalt [ slot ] ;
}
/* Do platform specific device initialization at pci_enable_device() time */
int pcibios_plat_dev_init ( struct pci_dev * dev )
{
return 0 ;
}