2019-05-27 08:55:01 +02:00
// SPDX-License-Identifier: GPL-2.0-or-later
2010-04-01 11:43:30 -07:00
/*
* Read address ranges from a Broadcom CNB20LE Host Bridge
*
* Copyright ( c ) 2010 Ira W . Snyder < iws @ ovro . caltech . edu >
*/
2011-01-06 10:12:24 -07:00
# include <linux/acpi.h>
2010-04-01 11:43:30 -07:00
# include <linux/delay.h>
# include <linux/dmi.h>
# include <linux/pci.h>
# include <linux/init.h>
# include <asm/pci_x86.h>
2011-10-28 16:28:03 -06:00
# include <asm/pci-direct.h>
2010-04-01 11:43:30 -07:00
# include "bus_numa.h"
2011-10-28 16:28:03 -06:00
static void __init cnb20le_res ( u8 bus , u8 slot , u8 func )
2010-04-01 11:43:30 -07:00
{
struct pci_root_info * info ;
2012-04-02 18:31:54 -07:00
struct pci_root_res * root_res ;
2010-04-01 11:43:30 -07:00
struct resource res ;
u16 word1 , word2 ;
u8 fbus , lbus ;
/* read the PCI bus numbers */
2011-10-28 16:28:03 -06:00
fbus = read_pci_config_byte ( bus , slot , func , 0x44 ) ;
lbus = read_pci_config_byte ( bus , slot , func , 0x45 ) ;
2012-04-02 18:31:54 -07:00
info = alloc_pci_root_info ( fbus , lbus , 0 , 0 ) ;
2010-04-01 11:43:30 -07:00
/*
* Add the legacy IDE ports on bus 0
*
* These do not exist anywhere in the bridge registers , AFAICT . I do
* not have the datasheet , so this is the best I can do .
*/
if ( fbus = = 0 ) {
update_res ( info , 0x01f0 , 0x01f7 , IORESOURCE_IO , 0 ) ;
update_res ( info , 0x03f6 , 0x03f6 , IORESOURCE_IO , 0 ) ;
update_res ( info , 0x0170 , 0x0177 , IORESOURCE_IO , 0 ) ;
update_res ( info , 0x0376 , 0x0376 , IORESOURCE_IO , 0 ) ;
update_res ( info , 0xffa0 , 0xffaf , IORESOURCE_IO , 0 ) ;
}
/* read the non-prefetchable memory window */
2011-10-28 16:28:03 -06:00
word1 = read_pci_config_16 ( bus , slot , func , 0xc0 ) ;
word2 = read_pci_config_16 ( bus , slot , func , 0xc2 ) ;
2010-04-01 11:43:30 -07:00
if ( word1 ! = word2 ) {
2018-10-25 14:52:31 +01:00
res . start = ( ( resource_size_t ) word1 < < 16 ) | 0x0000 ;
res . end = ( ( resource_size_t ) word2 < < 16 ) | 0xffff ;
2010-04-01 11:43:30 -07:00
res . flags = IORESOURCE_MEM ;
update_res ( info , res . start , res . end , res . flags , 0 ) ;
}
/* read the prefetchable memory window */
2011-10-28 16:28:03 -06:00
word1 = read_pci_config_16 ( bus , slot , func , 0xc4 ) ;
word2 = read_pci_config_16 ( bus , slot , func , 0xc6 ) ;
2010-04-01 11:43:30 -07:00
if ( word1 ! = word2 ) {
2014-04-25 11:01:08 -06:00
res . start = ( ( resource_size_t ) word1 < < 16 ) | 0x0000 ;
res . end = ( ( resource_size_t ) word2 < < 16 ) | 0xffff ;
2010-04-01 11:43:30 -07:00
res . flags = IORESOURCE_MEM | IORESOURCE_PREFETCH ;
update_res ( info , res . start , res . end , res . flags , 0 ) ;
}
/* read the IO port window */
2011-10-28 16:28:03 -06:00
word1 = read_pci_config_16 ( bus , slot , func , 0xd0 ) ;
word2 = read_pci_config_16 ( bus , slot , func , 0xd2 ) ;
2010-04-01 11:43:30 -07:00
if ( word1 ! = word2 ) {
res . start = word1 ;
res . end = word2 ;
res . flags = IORESOURCE_IO ;
update_res ( info , res . start , res . end , res . flags , 0 ) ;
}
/* print information about this host bridge */
res . start = fbus ;
res . end = lbus ;
res . flags = IORESOURCE_BUS ;
2011-10-28 16:28:03 -06:00
printk ( KERN_INFO " CNB20LE PCI Host Bridge (domain 0000 %pR) \n " , & res ) ;
2010-04-01 11:43:30 -07:00
2012-04-02 18:31:54 -07:00
list_for_each_entry ( root_res , & info - > resources , list )
printk ( KERN_INFO " host bridge window %pR \n " , & root_res - > res ) ;
2010-04-01 11:43:30 -07:00
}
2011-10-28 16:28:03 -06:00
static int __init broadcom_postcore_init ( void )
{
u8 bus = 0 , slot = 0 ;
u32 id ;
u16 vendor , device ;
# ifdef CONFIG_ACPI
/*
* We should get host bridge information from ACPI unless the BIOS
* doesn ' t support it .
*/
2017-12-01 15:08:12 +01:00
if ( ! acpi_disabled & & acpi_os_get_root_pointer ( ) )
2011-10-28 16:28:03 -06:00
return 0 ;
# endif
id = read_pci_config ( bus , slot , 0 , PCI_VENDOR_ID ) ;
vendor = id & 0xffff ;
device = ( id > > 16 ) & 0xffff ;
if ( vendor = = PCI_VENDOR_ID_SERVERWORKS & &
device = = PCI_DEVICE_ID_SERVERWORKS_LE ) {
cnb20le_res ( bus , slot , 0 ) ;
cnb20le_res ( bus , slot , 1 ) ;
}
return 0 ;
}
2010-04-01 11:43:30 -07:00
2011-10-28 16:28:03 -06:00
postcore_initcall ( broadcom_postcore_init ) ;