@ -2,7 +2,7 @@
* ( C ) Copyright 2001 Sysgo Real - Time Solutions , GmbH < www . elinos . com >
* Andreas Heppel < aheppel @ sysgo . de >
*
* ( C ) Copyright 2002
* ( C ) Copyright 2002 , 2003
* Wolfgang Denk , DENX Software Engineering , wd @ denx . de .
*
* See file CREDITS for list of people who contributed to this
@ -85,13 +85,13 @@ PCI_OP(write, word, u16, )
PCI_OP ( write , dword , u32 , )
# define PCI_READ_VIA_DWORD_OP(size, type, off_mask) \
int pci_hose_read_config_ # # size # # _via_dword ( struct pci_controller * hose , \
int pci_hose_read_config_ # # size # # _via_dword ( struct pci_controller * hose , \
pci_dev_t dev , \
int offset , type val ) \
{ \
u32 val32 ; \
\
if ( pci_hose_read_config_dword ( hose , dev , offset & 0xfc , & val32 ) < 0 ) \
if ( pci_hose_read_config_dword ( hose , dev , offset & 0xfc , & val32 ) < 0 ) \
return - 1 ; \
\
* val = ( val32 > > ( ( offset & ( int ) off_mask ) * 8 ) ) ; \
@ -100,13 +100,13 @@ int pci_hose_read_config_##size##_via_dword(struct pci_controller *hose, \
}
# define PCI_WRITE_VIA_DWORD_OP(size, type, off_mask, val_mask) \
int pci_hose_write_config_ # # size # # _via_dword ( struct pci_controller * hose , \
int pci_hose_write_config_ # # size # # _via_dword ( struct pci_controller * hose , \
pci_dev_t dev , \
int offset , type val ) \
{ \
u32 val32 , mask , ldata ; \
\
if ( pci_hose_read_config_dword ( hose , dev , offset & 0xfc , & val32 ) < 0 ) \
if ( pci_hose_read_config_dword ( hose , dev , offset & 0xfc , & val32 ) < 0 ) \
return - 1 ; \
\
mask = val_mask ; \
@ -114,7 +114,7 @@ int pci_hose_write_config_##size##_via_dword(struct pci_controller *hose, \
mask < < = ( ( mask & ( int ) off_mask ) * 8 ) ; \
val32 = ( val32 & ~ mask ) | ldata ; \
\
if ( pci_hose_write_config_dword ( hose , dev , offset & 0xfc , val32 ) < 0 ) \
if ( pci_hose_write_config_dword ( hose , dev , offset & 0xfc , val32 ) < 0 ) \
return - 1 ; \
\
return 0 ; \
@ -143,13 +143,12 @@ void pci_register_hose(struct pci_controller* hose)
* phose = hose ;
}
struct pci_controller * pci_bus_to_hose ( int bus )
struct pci_controller * pci_bus_to_hose ( int bus )
{
struct pci_controller * hose ;
for ( hose = hose_head ; hose ; hose = hose - > next )
if ( bus > = hose - > first_busno & &
bus < = hose - > last_busno )
if ( bus > = hose - > first_busno & & bus < = hose - > last_busno )
return hose ;
return NULL ;
@ -178,16 +177,13 @@ pci_dev_t pci_find_devices(struct pci_device_id *ids, int index)
# endif
bdf + = PCI_BDF ( 0 , 0 , 1 ) )
{
if ( ! PCI_FUNC ( bdf ) )
{
if ( ! PCI_FUNC ( bdf ) ) {
pci_read_config_byte ( bdf ,
PCI_HEADER_TYPE ,
& header_type ) ;
found_multi = header_type & 0x80 ;
}
else
{
} else {
if ( ! found_multi )
continue ;
}
@ -228,7 +224,7 @@ pci_dev_t pci_find_device(unsigned int vendor, unsigned int device, int index)
*
*/
unsigned long pci_hose_phys_to_bus ( struct pci_controller * hose ,
unsigned long pci_hose_phys_to_bus ( struct pci_controller * hose ,
unsigned long phys_addr ,
unsigned long flags )
{
@ -236,14 +232,12 @@ unsigned long pci_hose_phys_to_bus(struct pci_controller* hose,
unsigned long bus_addr ;
int i ;
if ( ! hose )
{
printf ( " pci_hose_phys_to_bus: %s \n " , " invalid hose " ) ;
if ( ! hose ) {
printf ( " pci_hose_phys_to_bus: %s \n " , " invalid hose " ) ;
goto Done ;
}
for ( i = 0 ; i < hose - > region_count ; i + + )
{
for ( i = 0 ; i < hose - > region_count ; i + + ) {
res = & hose - > regions [ i ] ;
if ( ( ( res - > flags ^ flags ) & PCI_REGION_TYPE ) ! = 0 )
@ -252,15 +246,14 @@ unsigned long pci_hose_phys_to_bus(struct pci_controller* hose,
bus_addr = phys_addr - res - > phys_start + res - > bus_start ;
if ( bus_addr > = res - > bus_start & &
bus_addr < res - > bus_start + res - > size )
{
bus_addr < res - > bus_start + res - > size ) {
return bus_addr ;
}
}
printf ( " pci_hose_phys_to_bus: %s \n " , " invalid physical address " ) ;
printf ( " pci_hose_phys_to_bus: %s \n " , " invalid physical address " ) ;
Done :
Done :
return 0 ;
}
@ -271,29 +264,26 @@ unsigned long pci_hose_bus_to_phys(struct pci_controller* hose,
struct pci_region * res ;
int i ;
if ( ! hose )
{
printf ( " pci_hose_bus_to_phys: %s \n " , " invalid hose " ) ;
if ( ! hose ) {
printf ( " pci_hose_bus_to_phys: %s \n " , " invalid hose " ) ;
goto Done ;
}
for ( i = 0 ; i < hose - > region_count ; i + + )
{
for ( i = 0 ; i < hose - > region_count ; i + + ) {
res = & hose - > regions [ i ] ;
if ( ( ( res - > flags ^ flags ) & PCI_REGION_TYPE ) ! = 0 )
continue ;
if ( bus_addr > = res - > bus_start & &
bus_addr < res - > bus_start + res - > size )
{
bus_addr < res - > bus_start + res - > size ) {
return bus_addr - res - > bus_start + res - > phys_start ;
}
}
printf ( " pci_hose_bus_to_phys: %s \n " , " invalid physical address " ) ;
printf ( " pci_hose_bus_to_phys: %s \n " , " invalid physical address " ) ;
Done :
Done :
return 0 ;
}
@ -311,14 +301,14 @@ int pci_hose_config_device(struct pci_controller *hose,
unsigned char pin ;
int bar , found_mem64 ;
DEBUGF ( " PCI Config: I/O=0x%lx, Memory=0x%lx, Command=0x%lx \n " , io , mem , command ) ;
DEBUGF ( " PCI Config: I/O=0x%lx, Memory=0x%lx, Command=0x%lx \n " ,
io , mem , command ) ;
pci_hose_write_config_dword ( hose , dev , PCI_COMMAND , 0 ) ;
pci_hose_write_config_dword ( hose , dev , PCI_COMMAND , 0 ) ;
for ( bar = PCI_BASE_ADDRESS_0 ; bar < PCI_BASE_ADDRESS_5 ; bar + = 4 )
{
pci_hose_write_config_dword ( hose , dev , bar , 0xffffffff ) ;
pci_hose_read_config_dword ( hose , dev , bar , & bar_response ) ;
for ( bar = PCI_BASE_ADDRESS_0 ; bar < PCI_BASE_ADDRESS_5 ; bar + = 4 ) {
pci_hose_write_config_dword ( hose , dev , bar , 0xffffffff ) ;
pci_hose_read_config_dword ( hose , dev , bar , & bar_response ) ;
if ( ! bar_response )
continue ;
@ -326,51 +316,51 @@ int pci_hose_config_device(struct pci_controller *hose,
found_mem64 = 0 ;
/* Check the BAR type and set our address mask */
if ( bar_response & PCI_BASE_ADDRESS_SPACE )
{
if ( bar_response & PCI_BASE_ADDRESS_SPACE ) {
bar_size = ~ ( bar_response & PCI_BASE_ADDRESS_IO_MASK ) + 1 ;
bar_value = io ;
/* round up region base address to a multiple of size */
io = ( ( io - 1 ) | ( bar_size - 1 ) ) + 1 ;
}
else
{
if ( ( bar_response & PCI_BASE_ADDRESS_MEM_TYPE_MASK ) = =
bar_value = io ;
/* compute new region base address */
io = io + bar_size ;
} else {
if ( ( bar_response & PCI_BASE_ADDRESS_MEM_TYPE_MASK ) = =
PCI_BASE_ADDRESS_MEM_TYPE_64 )
found_mem64 = 1 ;
bar_size = ~ ( bar_response & PCI_BASE_ADDRESS_MEM_MASK ) + 1 ;
bar_value = mem ;
/* round up region base address to multiple of size */
mem = ( ( mem - 1 ) | ( bar_size - 1 ) ) + 1 ;
bar_value = mem ;
/* compute new region base address */
mem = mem + bar_size ;
}
/* Write it out and update our limit */
pci_hose_write_config_dword ( hose , dev , bar , bar_value ) ;
pci_hose_write_config_dword ( hose , dev , bar , bar_value ) ;
if ( found_mem64 )
{
if ( found_mem64 ) {
bar + = 4 ;
pci_hose_write_config_dword ( hose , dev , bar , 0x00000000 ) ;
pci_hose_write_config_dword ( hose , dev , bar , 0x00000000 ) ;
}
}
/* Configure Cache Line Size Register */
pci_hose_write_config_byte ( hose , dev , PCI_CACHE_LINE_SIZE , 0x08 ) ;
pci_hose_write_config_byte ( hose , dev , PCI_CACHE_LINE_SIZE , 0x08 ) ;
/* Configure Latency Timer */
pci_hose_write_config_byte ( hose , dev , PCI_LATENCY_TIMER , 0x80 ) ;
pci_hose_write_config_byte ( hose , dev , PCI_LATENCY_TIMER , 0x80 ) ;
/* Disable interrupt line, if device says it wants to use interrupts */
pci_hose_read_config_byte ( hose , dev , PCI_INTERRUPT_PIN , & pin ) ;
if ( pin ! = 0 )
{
pci_hose_write_config_byte ( hose , dev , PCI_INTERRUPT_LINE , 0xff ) ;
pci_hose_read_config_byte ( hose , dev , PCI_INTERRUPT_PIN , & pin ) ;
if ( pin ! = 0 ) {
pci_hose_write_config_byte ( hose , dev , PCI_INTERRUPT_LINE , 0xff ) ;
}
pci_hose_read_config_dword ( hose , dev , PCI_COMMAND , & old_command ) ;
pci_hose_write_config_dword ( hose , dev , PCI_COMMAND ,
( old_command & 0xffff0000 ) | command ) ;
pci_hose_read_config_dword ( hose , dev , PCI_COMMAND , & old_command ) ;
pci_hose_write_config_dword ( hose , dev , PCI_COMMAND ,
( old_command & 0xffff0000 ) | command ) ;
return 0 ;
}
@ -389,15 +379,13 @@ struct pci_config_table *pci_find_config(struct pci_controller *hose,
{
struct pci_config_table * table ;
for ( table = hose - > config_table ; table & & table - > vendor ; table + + )
{
for ( table = hose - > config_table ; table & & table - > vendor ; table + + ) {
if ( ( table - > vendor = = PCI_ANY_ID | | table - > vendor = = vendor ) & &
( table - > device = = PCI_ANY_ID | | table - > device = = device ) & &
( table - > class = = PCI_ANY_ID | | table - > class = = class ) & &
( table - > bus = = PCI_ANY_ID | | table - > bus = = bus ) & &
( table - > dev = = PCI_ANY_ID | | table - > dev = = dev ) & &
( table - > func = = PCI_ANY_ID | | table - > func = = func ) )
{
( table - > func = = PCI_ANY_ID | | table - > func = = func ) ) {
return table ;
}
}