2006-09-27 10:59:17 +04:00
/*
* Low - Level PCI Support for the SH7780
*
* Dustin McIntire ( dustin @ sensoria . com )
* Derived from arch / i386 / kernel / pci - * . c which bore the message :
* ( c ) 1999 - - 2000 Martin Mares < mj @ ucw . cz >
*
* Ported to the new API by Paul Mundt < lethal @ linux - sh . org >
* With cleanup by Paul van Gool < pvangool @ mimotech . com >
*
* May be copied or modified under the terms of the GNU General Public
* License . See linux / COPYING for more information .
*
*/
# undef DEBUG
# include <linux/types.h>
# include <linux/kernel.h>
# include <linux/init.h>
# include <linux/pci.h>
# include <linux/errno.h>
# include <linux/delay.h>
2006-09-27 11:43:28 +04:00
# include "pci-sh4.h"
2006-09-27 10:59:17 +04:00
2009-03-11 09:46:14 +03:00
int __init sh7780_pci_init ( struct pci_channel * chan )
2006-09-27 10:59:17 +04:00
{
2006-09-27 11:43:28 +04:00
unsigned int id ;
2009-04-17 10:05:19 +04:00
const char * type = NULL ;
int ret ;
2006-09-27 10:59:17 +04:00
2009-04-17 10:05:19 +04:00
printk ( KERN_NOTICE " PCI: Starting intialization. \n " ) ;
2006-09-27 10:59:17 +04:00
2008-02-19 15:35:04 +03:00
chan - > reg_base = 0xfe040000 ;
2008-02-19 15:35:14 +03:00
chan - > io_base = 0xfe200000 ;
2008-02-19 15:35:04 +03:00
2009-04-17 10:05:19 +04:00
/* Enable CPU access to the PCIC registers. */
__raw_writel ( PCIECR_ENBL , PCIECR ) ;
2006-09-27 10:59:17 +04:00
2009-04-17 10:05:19 +04:00
id = __raw_readw ( chan - > reg_base + SH7780_PCIVID ) ;
if ( id ! = SH7780_VENDOR_ID ) {
printk ( KERN_ERR " PCI: Unknown vendor ID 0x%04x. \n " , id ) ;
return - ENODEV ;
2007-03-12 08:38:59 +03:00
}
2009-04-17 10:05:19 +04:00
id = __raw_readw ( chan - > reg_base + SH7780_PCIDID ) ;
type = ( id = = SH7763_DEVICE_ID ) ? " SH7763 " :
( id = = SH7780_DEVICE_ID ) ? " SH7780 " :
( id = = SH7781_DEVICE_ID ) ? " SH7781 " :
( id = = SH7785_DEVICE_ID ) ? " SH7785 " :
NULL ;
if ( unlikely ( ! type ) ) {
printk ( KERN_ERR " PCI: Found an unsupported Renesas host "
" controller, device id 0x%04x. \n " , id ) ;
return - EINVAL ;
2006-09-27 10:59:17 +04:00
}
2009-04-17 10:05:19 +04:00
printk ( KERN_NOTICE " PCI: Found a Renesas %s host "
" controller, revision %d. \n " , type ,
__raw_readb ( chan - > reg_base + SH7780_PCIRID ) ) ;
2009-03-11 09:46:14 +03:00
if ( ( ret = sh4_pci_check_direct ( chan ) ) ! = 0 )
2006-09-27 10:59:17 +04:00
return ret ;
2009-04-17 11:38:00 +04:00
/*
* Platform specific initialization ( BSC registers , and memory space
* mapping ) will be called via the platform defined function
* pcibios_init_platform ( ) .
*/
2006-09-27 10:59:17 +04:00
return pcibios_init_platform ( ) ;
}
2009-04-17 11:38:00 +04:00
extern u8 pci_cache_line_size ;
2009-03-11 09:41:51 +03:00
int __init sh7780_pcic_init ( struct pci_channel * chan ,
struct sh4_pci_address_map * map )
2006-09-27 10:59:17 +04:00
{
u32 word ;
2009-04-17 11:38:00 +04:00
/*
* Set the class and sub - class codes .
*/
2009-04-17 10:08:01 +04:00
__raw_writeb ( PCI_CLASS_BRIDGE_HOST > > 8 ,
chan - > reg_base + SH7780_PCIBCC ) ;
__raw_writeb ( PCI_CLASS_BRIDGE_HOST & 0xff ,
chan - > reg_base + SH7780_PCISUB ) ;
2009-04-17 09:09:09 +04:00
2009-04-17 11:38:00 +04:00
pci_cache_line_size = pci_read_reg ( chan , SH7780_PCICLS ) / 4 ;
2006-09-27 10:59:17 +04:00
/* set the command/status bits to:
* Wait Cycle Control + Parity Enable + Bus Master +
* Mem space enable
*/
2009-03-11 09:41:51 +03:00
pci_write_reg ( chan , 0x00000046 , SH7780_PCICMD ) ;
2006-09-27 10:59:17 +04:00
/* Set IO and Mem windows to local address
* Make PCI and local address the same for easy 1 to 1 mapping
*/
2009-03-11 09:41:51 +03:00
pci_write_reg ( chan , map - > window0 . size - 0xfffff , SH4_PCILSR0 ) ;
pci_write_reg ( chan , map - > window1 . size - 0xfffff , SH4_PCILSR1 ) ;
2006-09-27 10:59:17 +04:00
/* Set the values on window 0 PCI config registers */
2009-03-11 09:41:51 +03:00
pci_write_reg ( chan , map - > window0 . base , SH4_PCILAR0 ) ;
pci_write_reg ( chan , map - > window0 . base , SH7780_PCIMBAR0 ) ;
2006-09-27 10:59:17 +04:00
/* Set the values on window 1 PCI config registers */
2009-03-11 09:41:51 +03:00
pci_write_reg ( chan , map - > window1 . base , SH4_PCILAR1 ) ;
pci_write_reg ( chan , map - > window1 . base , SH7780_PCIMBAR1 ) ;
2006-09-27 10:59:17 +04:00
2007-03-28 19:07:35 +04:00
/* Apply any last-minute PCIC fixups */
2009-03-11 09:41:51 +03:00
pci_fixup_pcic ( chan ) ;
2006-09-27 10:59:17 +04:00
/* SH7780 init done, set central function init complete */
/* use round robin mode to stop a device starving/overruning */
2006-09-27 11:43:28 +04:00
word = SH4_PCICR_PREFIX | SH4_PCICR_CFIN | SH4_PCICR_FTO ;
2009-03-11 09:41:51 +03:00
pci_write_reg ( chan , word , SH4_PCICR ) ;
2006-09-27 10:59:17 +04:00
2009-03-11 09:46:14 +03:00
return 0 ;
2006-09-27 10:59:17 +04:00
}