2005-04-16 15:20:36 -07:00
/*
* Exceptions for specific devices . Usually work - arounds for fatal design flaws .
*/
2005-10-25 10:28:42 -07:00
# include <linux/delay.h>
# include <linux/dmi.h>
2005-04-16 15:20:36 -07:00
# include <linux/pci.h>
2012-05-17 08:31:29 +01:00
# include <linux/vgaarb.h>
x86/PCI: Mark ATI SBx00 HPET BAR as IORESOURCE_PCI_FIXED
Bodo reported that on the Asrock M3A UCC, v3.12.6 hangs during boot unless
he uses "pci=nocrs". This regression was caused by 7bc5e3f2be32 ("x86/PCI:
use host bridge _CRS info by default on 2008 and newer machines"), which
appeared in v2.6.34.
The reason is that the HPET address appears in a PCI device BAR, and this
address is not contained in any of the host bridge windows. Linux moves
the PCI BAR into a window, but the original address was published via the
HPET table and an ACPI device, so changing the BAR is a bad idea. Here's
the dmesg info:
ACPI: HPET id: 0x43538301 base: 0xfed00000
pci_root PNP0A03:00: host bridge window [mem 0xd0000000-0xdfffffff]
pci_root PNP0A03:00: host bridge window [mem 0xf0000000-0xfebfffff]
pci 0000:00:14.0: [1002:4385] type 0 class 0x000c05
pci 0000:00:14.0: reg 14: [mem 0xfed00000-0xfed003ff]
hpet0: at MMIO 0xfed00000, IRQs 2, 8, 0, 0
pnp 00:06: Plug and Play ACPI device, IDs PNP0103 (active)
pnp 00:06: [mem 0xfed00000-0xfed003ff]
When we notice the BAR is not in a host bridge window, we try to move it,
but that causes a hang shortly thereafter:
pci 0000:00:14.0: no compatible bridge window for [mem 0xfed00000-0xfed003ff]
pci 0000:00:14.0: BAR 1: assigned [mem 0xf0000000-0xf00003ff]
This patch marks the BAR as IORESOURCE_PCI_FIXED to prevent Linux from
moving it. This depends on a previous patch ("x86/PCI: Don't try to move
IORESOURCE_PCI_FIXED resources") to check for this flag when
pci_claim_resource() fails.
Link: https://bugzilla.kernel.org/show_bug.cgi?id=68591
Reported-and-tested-by: Bodo Eggert <7eggert@gmx.de>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
2014-04-14 15:35:21 -06:00
# include <asm/hpet.h>
2008-12-27 18:32:28 +05:30
# include <asm/pci_x86.h>
2005-04-16 15:20:36 -07:00
2012-12-21 14:02:53 -08:00
static void pci_fixup_i450nx ( struct pci_dev * d )
2005-04-16 15:20:36 -07:00
{
/*
* i450NX - - Find and scan all secondary buses on all PXB ' s .
*/
int pxb , reg ;
u8 busno , suba , subb ;
2007-12-17 14:09:40 -07:00
dev_warn ( & d - > dev , " Searching for i450NX host bridges \n " ) ;
2005-04-16 15:20:36 -07:00
reg = 0xd0 ;
2008-01-30 13:33:00 +01:00
for ( pxb = 0 ; pxb < 2 ; pxb + + ) {
2005-04-16 15:20:36 -07:00
pci_read_config_byte ( d , reg + + , & busno ) ;
pci_read_config_byte ( d , reg + + , & suba ) ;
pci_read_config_byte ( d , reg + + , & subb ) ;
2008-07-23 17:00:13 -06:00
dev_dbg ( & d - > dev , " i450NX PXB %d: %02x/%02x/%02x \n " , pxb , busno ,
suba , subb ) ;
2005-04-16 15:20:36 -07:00
if ( busno )
2014-01-24 11:47:05 -07:00
pcibios_scan_root ( busno ) ; /* Bus A */
2005-04-16 15:20:36 -07:00
if ( suba < subb )
2014-01-24 11:47:05 -07:00
pcibios_scan_root ( suba + 1 ) ; /* Bus B */
2005-04-16 15:20:36 -07:00
}
pcibios_last_bus = - 1 ;
}
DECLARE_PCI_FIXUP_HEADER ( PCI_VENDOR_ID_INTEL , PCI_DEVICE_ID_INTEL_82451NX , pci_fixup_i450nx ) ;
2012-12-21 14:02:53 -08:00
static void pci_fixup_i450gx ( struct pci_dev * d )
2005-04-16 15:20:36 -07:00
{
/*
* i450GX and i450KX - - Find and scan all secondary buses .
* ( called separately for each PCI bridge found )
*/
u8 busno ;
pci_read_config_byte ( d , 0x4a , & busno ) ;
2007-12-17 14:09:40 -07:00
dev_info ( & d - > dev , " i440KX/GX host bridge; secondary bus %02x \n " , busno ) ;
2014-01-24 11:47:05 -07:00
pcibios_scan_root ( busno ) ;
2005-04-16 15:20:36 -07:00
pcibios_last_bus = - 1 ;
}
DECLARE_PCI_FIXUP_HEADER ( PCI_VENDOR_ID_INTEL , PCI_DEVICE_ID_INTEL_82454GX , pci_fixup_i450gx ) ;
2012-12-21 14:02:53 -08:00
static void pci_fixup_umc_ide ( struct pci_dev * d )
2005-04-16 15:20:36 -07:00
{
/*
* UM8886BF IDE controller sets region type bits incorrectly ,
* therefore they look like memory despite of them being I / O .
*/
int i ;
2007-12-17 14:09:40 -07:00
dev_warn ( & d - > dev , " Fixing base address flags \n " ) ;
2008-01-30 13:33:00 +01:00
for ( i = 0 ; i < 4 ; i + + )
2005-04-16 15:20:36 -07:00
d - > resource [ i ] . flags | = PCI_BASE_ADDRESS_SPACE_IO ;
}
DECLARE_PCI_FIXUP_HEADER ( PCI_VENDOR_ID_UMC , PCI_DEVICE_ID_UMC_UM8886BF , pci_fixup_umc_ide ) ;
2012-12-21 14:02:53 -08:00
static void pci_fixup_latency ( struct pci_dev * d )
2005-04-16 15:20:36 -07:00
{
/*
* SiS 5597 and 5598 chipsets require latency timer set to
* at most 32 to avoid lockups .
*/
2007-12-17 14:09:40 -07:00
dev_dbg ( & d - > dev , " Setting max latency to 32 \n " ) ;
2005-04-16 15:20:36 -07:00
pcibios_max_latency = 32 ;
}
DECLARE_PCI_FIXUP_HEADER ( PCI_VENDOR_ID_SI , PCI_DEVICE_ID_SI_5597 , pci_fixup_latency ) ;
DECLARE_PCI_FIXUP_HEADER ( PCI_VENDOR_ID_SI , PCI_DEVICE_ID_SI_5598 , pci_fixup_latency ) ;
2012-12-21 14:02:53 -08:00
static void pci_fixup_piix4_acpi ( struct pci_dev * d )
2005-04-16 15:20:36 -07:00
{
/*
* PIIX4 ACPI device : hardwired IRQ9
*/
d - > irq = 9 ;
}
DECLARE_PCI_FIXUP_HEADER ( PCI_VENDOR_ID_INTEL , PCI_DEVICE_ID_INTEL_82371AB_3 , pci_fixup_piix4_acpi ) ;
/*
* Addresses issues with problems in the memory write queue timer in
* certain VIA Northbridges . This bugfix is per VIA ' s specifications ,
* except for the KL133 / KM133 : clearing bit 5 on those Northbridges seems
* to trigger a bug in its integrated ProSavage video card , which
* causes screen corruption . We only clear bits 6 and 7 for that chipset ,
* until VIA can provide us with definitive information on why screen
* corruption occurs , and what exactly those bits do .
*
* VIA 8363 , 8622 , 8361 Northbridges :
* - bits 5 , 6 , 7 at offset 0x55 need to be turned off
* VIA 8367 ( KT266x ) Northbridges :
* - bits 5 , 6 , 7 at offset 0x95 need to be turned off
* VIA 8363 rev 0x81 / 0x84 ( KL133 / KM133 ) Northbridges :
* - bits 6 , 7 at offset 0x55 need to be turned off
*/
# define VIA_8363_KL133_REVISION_ID 0x81
# define VIA_8363_KM133_REVISION_ID 0x84
2006-12-04 15:14:45 -08:00
static void pci_fixup_via_northbridge_bug ( struct pci_dev * d )
2005-04-16 15:20:36 -07:00
{
u8 v ;
int where = 0x55 ;
int mask = 0x1f ; /* clear bits 5, 6, 7 by default */
if ( d - > device = = PCI_DEVICE_ID_VIA_8367_0 ) {
/* fix pci bus latency issues resulted by NB bios error
it appears on bug free ^ Wreduced kt266x ' s bios forces
NB latency to zero */
pci_write_config_byte ( d , PCI_LATENCY_TIMER , 0 ) ;
2008-01-30 13:33:00 +01:00
where = 0x95 ; /* the memory write queue timer register is
2005-04-16 15:20:36 -07:00
different for the KT266x ' s : 0x95 not 0x55 */
} else if ( d - > device = = PCI_DEVICE_ID_VIA_8363_0 & &
2007-06-08 15:46:36 -07:00
( d - > revision = = VIA_8363_KL133_REVISION_ID | |
d - > revision = = VIA_8363_KM133_REVISION_ID ) ) {
2005-04-16 15:20:36 -07:00
mask = 0x3f ; /* clear only bits 6 and 7; clearing bit 5
causes screen corruption on the KL133 / KM133 */
}
pci_read_config_byte ( d , where , & v ) ;
if ( v & ~ mask ) {
2007-12-17 14:09:40 -07:00
dev_warn ( & d - > dev , " Disabling VIA memory write queue (PCI ID %04x, rev %02x): [%02x] %02x & %02x -> %02x \n " , \
2007-06-08 15:46:36 -07:00
d - > device , d - > revision , where , v , mask , v & mask ) ;
2005-04-16 15:20:36 -07:00
v & = mask ;
pci_write_config_byte ( d , where , v ) ;
}
}
DECLARE_PCI_FIXUP_HEADER ( PCI_VENDOR_ID_VIA , PCI_DEVICE_ID_VIA_8363_0 , pci_fixup_via_northbridge_bug ) ;
DECLARE_PCI_FIXUP_HEADER ( PCI_VENDOR_ID_VIA , PCI_DEVICE_ID_VIA_8622 , pci_fixup_via_northbridge_bug ) ;
DECLARE_PCI_FIXUP_HEADER ( PCI_VENDOR_ID_VIA , PCI_DEVICE_ID_VIA_8361 , pci_fixup_via_northbridge_bug ) ;
DECLARE_PCI_FIXUP_HEADER ( PCI_VENDOR_ID_VIA , PCI_DEVICE_ID_VIA_8367_0 , pci_fixup_via_northbridge_bug ) ;
2006-12-04 15:14:45 -08:00
DECLARE_PCI_FIXUP_RESUME ( PCI_VENDOR_ID_VIA , PCI_DEVICE_ID_VIA_8363_0 , pci_fixup_via_northbridge_bug ) ;
DECLARE_PCI_FIXUP_RESUME ( PCI_VENDOR_ID_VIA , PCI_DEVICE_ID_VIA_8622 , pci_fixup_via_northbridge_bug ) ;
DECLARE_PCI_FIXUP_RESUME ( PCI_VENDOR_ID_VIA , PCI_DEVICE_ID_VIA_8361 , pci_fixup_via_northbridge_bug ) ;
DECLARE_PCI_FIXUP_RESUME ( PCI_VENDOR_ID_VIA , PCI_DEVICE_ID_VIA_8367_0 , pci_fixup_via_northbridge_bug ) ;
2005-04-16 15:20:36 -07:00
/*
* For some reasons Intel decided that certain parts of their
* 815 , 845 and some other chipsets must look like PCI - to - PCI bridges
* while they are obviously not . The 82801 family ( AA , AB , BAM / CAM ,
* BA / CA / DB and E ) PCI bridges are actually HUB - to - PCI ones , according
* to Intel terminology . These devices do forward all addresses from
* system to PCI bus no matter what are their window settings , so they are
* " transparent " ( or subtractive decoding ) from programmers point of view .
*/
2012-12-21 14:02:53 -08:00
static void pci_fixup_transparent_bridge ( struct pci_dev * dev )
2005-04-16 15:20:36 -07:00
{
2012-02-23 23:46:51 -08:00
if ( ( dev - > device & 0xff00 ) = = 0x2400 )
2005-04-16 15:20:36 -07:00
dev - > transparent = 1 ;
}
2012-02-23 23:46:51 -08:00
DECLARE_PCI_FIXUP_CLASS_HEADER ( PCI_VENDOR_ID_INTEL , PCI_ANY_ID ,
PCI_CLASS_BRIDGE_PCI , 8 , pci_fixup_transparent_bridge ) ;
2005-04-16 15:20:36 -07:00
/*
* Fixup for C1 Halt Disconnect problem on nForce2 systems .
*
* From information provided by " Allen Martin " < AMartin @ nvidia . com > :
*
* A hang is caused when the CPU generates a very fast CONNECT / HALT cycle
* sequence . Workaround is to set the SYSTEM_IDLE_TIMEOUT to 80 ns .
* This allows the state - machine and timer to return to a proper state within
* 80 ns of the CONNECT and probe appearing together . Since the CPU will not
* issue another HALT within 80 ns of the initial HALT , the failure condition
* is avoided .
*/
2006-12-04 15:14:45 -08:00
static void pci_fixup_nforce2 ( struct pci_dev * dev )
2005-04-16 15:20:36 -07:00
{
u32 val ;
/*
* Chip Old value New value
* C17 0x1F0FFF01 0x1F01FF01
* C18D 0x9F0FFF01 0x9F01FF01
*
* Northbridge chip version may be determined by
* reading the PCI revision ID ( 0xC1 or greater is C18D ) .
*/
pci_read_config_dword ( dev , 0x6c , & val ) ;
/*
* Apply fixup if needed , but don ' t touch disconnect state
*/
if ( ( val & 0x00FF0000 ) ! = 0x00010000 ) {
2007-12-17 14:09:40 -07:00
dev_warn ( & dev - > dev , " nForce2 C1 Halt Disconnect fixup \n " ) ;
2005-04-16 15:20:36 -07:00
pci_write_config_dword ( dev , 0x6c , ( val & 0xFF00FFFF ) | 0x00010000 ) ;
}
}
DECLARE_PCI_FIXUP_HEADER ( PCI_VENDOR_ID_NVIDIA , PCI_DEVICE_ID_NVIDIA_NFORCE2 , pci_fixup_nforce2 ) ;
2006-12-04 15:14:45 -08:00
DECLARE_PCI_FIXUP_RESUME ( PCI_VENDOR_ID_NVIDIA , PCI_DEVICE_ID_NVIDIA_NFORCE2 , pci_fixup_nforce2 ) ;
2005-04-16 15:20:36 -07:00
/* Max PCI Express root ports */
# define MAX_PCIEROOT 6
static int quirk_aspm_offset [ MAX_PCIEROOT < < 3 ] ;
2005-05-17 08:48:16 -07:00
# define GET_INDEX(a, b) ((((a) - PCI_DEVICE_ID_INTEL_MCH_PA) << 3) + ((b) & 7))
2005-04-16 15:20:36 -07:00
static int quirk_pcie_aspm_read ( struct pci_bus * bus , unsigned int devfn , int where , int size , u32 * value )
{
2008-02-10 09:45:28 -05:00
return raw_pci_read ( pci_domain_nr ( bus ) , bus - > number ,
devfn , where , size , value ) ;
2005-04-16 15:20:36 -07:00
}
/*
* Replace the original pci bus ops for write with a new one that will filter
* the request to insure ASPM cannot be enabled .
*/
static int quirk_pcie_aspm_write ( struct pci_bus * bus , unsigned int devfn , int where , int size , u32 value )
{
u8 offset ;
offset = quirk_aspm_offset [ GET_INDEX ( bus - > self - > device , devfn ) ] ;
if ( ( offset ) & & ( where = = offset ) )
2013-09-05 15:55:28 +08:00
value = value & ~ PCI_EXP_LNKCTL_ASPMC ;
2008-01-30 13:33:00 +01:00
2008-02-10 09:45:28 -05:00
return raw_pci_write ( pci_domain_nr ( bus ) , bus - > number ,
devfn , where , size , value ) ;
2005-04-16 15:20:36 -07:00
}
static struct pci_ops quirk_pcie_aspm_ops = {
. read = quirk_pcie_aspm_read ,
. write = quirk_pcie_aspm_write ,
} ;
/*
* Prevents PCI Express ASPM ( Active State Power Management ) being enabled .
*
* Save the register offset , where the ASPM control bits are located ,
* for each PCI Express device that is in the device list of
* the root port in an array for fast indexing . Replace the bus ops
* with the modified one .
*/
static void pcie_rootport_aspm_quirk ( struct pci_dev * pdev )
{
2013-09-05 15:55:28 +08:00
int i ;
2005-04-16 15:20:36 -07:00
struct pci_bus * pbus ;
struct pci_dev * dev ;
if ( ( pbus = pdev - > subordinate ) = = NULL )
return ;
/*
* Check if the DID of pdev matches one of the six root ports . This
* check is needed in the case this function is called directly by the
* hot - plug driver .
*/
if ( ( pdev - > device < PCI_DEVICE_ID_INTEL_MCH_PA ) | |
( pdev - > device > PCI_DEVICE_ID_INTEL_MCH_PC1 ) )
return ;
if ( list_empty ( & pbus - > devices ) ) {
/*
* If no device is attached to the root port at power - up or
* after hot - remove , the pbus - > devices is empty and this code
* will set the offsets to zero and the bus ops to parent ' s bus
* ops , which is unmodified .
2008-01-30 13:33:00 +01:00
*/
for ( i = GET_INDEX ( pdev - > device , 0 ) ; i < = GET_INDEX ( pdev - > device , 7 ) ; + + i )
2005-04-16 15:20:36 -07:00
quirk_aspm_offset [ i ] = 0 ;
2013-09-05 15:55:28 +08:00
pci_bus_set_ops ( pbus , pbus - > parent - > ops ) ;
2005-04-16 15:20:36 -07:00
} else {
/*
* If devices are attached to the root port at power - up or
* after hot - add , the code loops through the device list of
* each root port to save the register offsets and replace the
* bus ops .
*/
2013-09-05 15:55:28 +08:00
list_for_each_entry ( dev , & pbus - > devices , bus_list )
2005-04-16 15:20:36 -07:00
/* There are 0 to 8 devices attached to this bus */
2013-09-05 15:55:28 +08:00
quirk_aspm_offset [ GET_INDEX ( pdev - > device , dev - > devfn ) ] =
dev - > pcie_cap + PCI_EXP_LNKCTL ;
pci_bus_set_ops ( pbus , & quirk_pcie_aspm_ops ) ;
dev_info ( & pbus - > dev , " writes to ASPM control bits will be ignored \n " ) ;
2005-04-16 15:20:36 -07:00
}
2013-09-05 15:55:28 +08:00
2005-04-16 15:20:36 -07:00
}
2008-01-30 13:33:00 +01:00
DECLARE_PCI_FIXUP_FINAL ( PCI_VENDOR_ID_INTEL , PCI_DEVICE_ID_INTEL_MCH_PA , pcie_rootport_aspm_quirk ) ;
DECLARE_PCI_FIXUP_FINAL ( PCI_VENDOR_ID_INTEL , PCI_DEVICE_ID_INTEL_MCH_PA1 , pcie_rootport_aspm_quirk ) ;
DECLARE_PCI_FIXUP_FINAL ( PCI_VENDOR_ID_INTEL , PCI_DEVICE_ID_INTEL_MCH_PB , pcie_rootport_aspm_quirk ) ;
DECLARE_PCI_FIXUP_FINAL ( PCI_VENDOR_ID_INTEL , PCI_DEVICE_ID_INTEL_MCH_PB1 , pcie_rootport_aspm_quirk ) ;
DECLARE_PCI_FIXUP_FINAL ( PCI_VENDOR_ID_INTEL , PCI_DEVICE_ID_INTEL_MCH_PC , pcie_rootport_aspm_quirk ) ;
DECLARE_PCI_FIXUP_FINAL ( PCI_VENDOR_ID_INTEL , PCI_DEVICE_ID_INTEL_MCH_PC1 , pcie_rootport_aspm_quirk ) ;
2005-04-16 15:20:36 -07:00
2006-10-23 15:14:07 +09:00
/*
* Fixup to mark boot BIOS video selected by BIOS before it changes
*
* From information provided by " Jon Smirl " < jonsmirl @ gmail . com >
*
* The standard boot ROM sequence for an x86 machine uses the BIOS
* to select an initial video card for boot display . This boot video
* card will have it ' s BIOS copied to C0000 in system RAM .
* IORESOURCE_ROM_SHADOW is used to associate the boot video
* card with this copy . On laptops this copy has to be used since
* the main ROM may be compressed or combined with another image .
2014-01-31 10:28:23 +01:00
* See pci_map_rom ( ) for use of this flag . Before marking the device
* with IORESOURCE_ROM_SHADOW check if a vga_default_device is already set
* by either arch cde or vga - arbitration , if so only apply the fixup to this
* already determined primary video card .
2006-10-23 15:14:07 +09:00
*/
2012-12-21 14:02:53 -08:00
static void pci_fixup_video ( struct pci_dev * pdev )
2006-10-23 15:14:07 +09:00
{
struct pci_dev * bridge ;
struct pci_bus * bus ;
u16 config ;
/* Is VGA routed to us? */
bus = pdev - > bus ;
while ( bus ) {
bridge = bus - > self ;
/*
* From information provided by
* " David Miller " < davem @ davemloft . net >
* The bridge control register is valid for PCI header
* type BRIDGE , or CARDBUS . Host to PCI controllers use
* PCI header type NORMAL .
*/
2014-05-04 12:23:39 +08:00
if ( bridge & & ( pci_is_bridge ( bridge ) ) ) {
2006-10-23 15:14:07 +09:00
pci_read_config_word ( bridge , PCI_BRIDGE_CONTROL ,
& config ) ;
if ( ! ( config & PCI_BRIDGE_CTL_VGA ) )
return ;
}
bus = bus - > parent ;
}
2014-01-31 10:28:23 +01:00
if ( ! vga_default_device ( ) | | pdev = = vga_default_device ( ) ) {
pci_read_config_word ( pdev , PCI_COMMAND , & config ) ;
if ( config & ( PCI_COMMAND_IO | PCI_COMMAND_MEMORY ) ) {
pdev - > resource [ PCI_ROM_RESOURCE ] . flags | = IORESOURCE_ROM_SHADOW ;
2014-08-24 23:09:53 +02:00
dev_printk ( KERN_DEBUG , & pdev - > dev , " Video device with shadowed ROM \n " ) ;
2014-01-31 10:28:23 +01:00
}
2006-10-23 15:14:07 +09:00
}
}
2012-02-23 23:46:52 -08:00
DECLARE_PCI_FIXUP_CLASS_FINAL ( PCI_ANY_ID , PCI_ANY_ID ,
PCI_CLASS_DISPLAY_VGA , 8 , pci_fixup_video ) ;
2006-10-23 15:14:07 +09:00
2007-09-10 10:46:52 +02:00
2012-12-21 14:02:53 -08:00
static const struct dmi_system_id msi_k8t_dmi_table [ ] = {
2007-09-10 10:46:52 +02:00
{
. ident = " MSI-K8T-Neo2Fir " ,
. matches = {
DMI_MATCH ( DMI_SYS_VENDOR , " MSI " ) ,
DMI_MATCH ( DMI_PRODUCT_NAME , " MS-6702E " ) ,
} ,
} ,
{ }
} ;
/*
* The AMD - Athlon64 board MSI " K8T Neo2-FIR " disables the onboard sound
* card if a PCI - soundcard is added .
*
* The BIOS only gives options " DISABLED " and " AUTO " . This code sets
* the corresponding register - value to enable the soundcard .
*
* The soundcard is only enabled , if the mainborad is identified
* via DMI - tables and the soundcard is detected to be off .
*/
2012-12-21 14:02:53 -08:00
static void pci_fixup_msi_k8t_onboard_sound ( struct pci_dev * dev )
2007-09-10 10:46:52 +02:00
{
unsigned char val ;
if ( ! dmi_check_system ( msi_k8t_dmi_table ) )
return ; /* only applies to MSI K8T Neo2-FIR */
pci_read_config_byte ( dev , 0x50 , & val ) ;
if ( val & 0x40 ) {
pci_write_config_byte ( dev , 0x50 , val & ( ~ 0x40 ) ) ;
/* verify the change for status output */
pci_read_config_byte ( dev , 0x50 , & val ) ;
if ( val & 0x40 )
2007-12-17 14:09:40 -07:00
dev_info ( & dev - > dev , " Detected MSI K8T Neo2-FIR; "
2007-09-10 10:46:52 +02:00
" can't enable onboard soundcard! \n " ) ;
else
2007-12-17 14:09:40 -07:00
dev_info ( & dev - > dev , " Detected MSI K8T Neo2-FIR; "
" enabled onboard soundcard \n " ) ;
2007-09-10 10:46:52 +02:00
}
}
DECLARE_PCI_FIXUP_HEADER ( PCI_VENDOR_ID_VIA , PCI_DEVICE_ID_VIA_8237 ,
pci_fixup_msi_k8t_onboard_sound ) ;
DECLARE_PCI_FIXUP_RESUME ( PCI_VENDOR_ID_VIA , PCI_DEVICE_ID_VIA_8237 ,
pci_fixup_msi_k8t_onboard_sound ) ;
2005-10-25 10:28:42 -07:00
/*
* Some Toshiba laptops need extra code to enable their TI TSB43AB22 / A .
*
* We pretend to bring them out of full D3 state , and restore the proper
* IRQ , PCI cache line size , and BARs , otherwise the device won ' t function
* properly . In some cases , the device will generate an interrupt on
2006-10-03 22:21:02 +02:00
* the wrong IRQ line , causing any devices sharing the line it ' s
2005-10-25 10:28:42 -07:00
* * supposed * to use to be disabled by the kernel ' s IRQ debug code .
*/
static u16 toshiba_line_size ;
2012-12-21 14:02:53 -08:00
static const struct dmi_system_id toshiba_ohci1394_dmi_table [ ] = {
2005-10-25 10:28:42 -07:00
{
. ident = " Toshiba PS5 based laptop " ,
. matches = {
DMI_MATCH ( DMI_SYS_VENDOR , " TOSHIBA " ) ,
DMI_MATCH ( DMI_PRODUCT_VERSION , " PS5 " ) ,
} ,
} ,
{
. ident = " Toshiba PSM4 based laptop " ,
. matches = {
DMI_MATCH ( DMI_SYS_VENDOR , " TOSHIBA " ) ,
DMI_MATCH ( DMI_PRODUCT_VERSION , " PSM4 " ) ,
} ,
} ,
2005-12-17 09:27:50 -08:00
{
. ident = " Toshiba A40 based laptop " ,
. matches = {
DMI_MATCH ( DMI_SYS_VENDOR , " TOSHIBA " ) ,
DMI_MATCH ( DMI_PRODUCT_VERSION , " PSA40U " ) ,
} ,
} ,
2005-10-25 10:28:42 -07:00
{ }
} ;
2012-12-21 14:02:53 -08:00
static void pci_pre_fixup_toshiba_ohci1394 ( struct pci_dev * dev )
2005-10-25 10:28:42 -07:00
{
if ( ! dmi_check_system ( toshiba_ohci1394_dmi_table ) )
return ; /* only applies to certain Toshibas (so far) */
dev - > current_state = PCI_D3cold ;
pci_read_config_word ( dev , PCI_CACHE_LINE_SIZE , & toshiba_line_size ) ;
}
DECLARE_PCI_FIXUP_HEADER ( PCI_VENDOR_ID_TI , 0x8032 ,
pci_pre_fixup_toshiba_ohci1394 ) ;
2012-12-21 14:02:53 -08:00
static void pci_post_fixup_toshiba_ohci1394 ( struct pci_dev * dev )
2005-10-25 10:28:42 -07:00
{
if ( ! dmi_check_system ( toshiba_ohci1394_dmi_table ) )
return ; /* only applies to certain Toshibas (so far) */
/* Restore config space on Toshiba laptops */
pci_write_config_word ( dev , PCI_CACHE_LINE_SIZE , toshiba_line_size ) ;
2005-11-08 20:13:02 -08:00
pci_read_config_byte ( dev , PCI_INTERRUPT_LINE , ( u8 * ) & dev - > irq ) ;
2005-10-25 10:28:42 -07:00
pci_write_config_dword ( dev , PCI_BASE_ADDRESS_0 ,
pci_resource_start ( dev , 0 ) ) ;
pci_write_config_dword ( dev , PCI_BASE_ADDRESS_1 ,
pci_resource_start ( dev , 1 ) ) ;
}
DECLARE_PCI_FIXUP_ENABLE ( PCI_VENDOR_ID_TI , 0x8032 ,
pci_post_fixup_toshiba_ohci1394 ) ;
2006-01-14 13:21:23 -08:00
/*
* Prevent the BIOS trapping accesses to the Cyrix CS5530A video device
* configuration space .
*/
2006-12-04 15:14:45 -08:00
static void pci_early_fixup_cyrix_5530 ( struct pci_dev * dev )
2006-01-14 13:21:23 -08:00
{
u8 r ;
/* clear 'F4 Video Configuration Trap' bit */
pci_read_config_byte ( dev , 0x42 , & r ) ;
r & = 0xfd ;
pci_write_config_byte ( dev , 0x42 , r ) ;
}
DECLARE_PCI_FIXUP_EARLY ( PCI_VENDOR_ID_CYRIX , PCI_DEVICE_ID_CYRIX_5530_LEGACY ,
pci_early_fixup_cyrix_5530 ) ;
2006-12-04 15:14:45 -08:00
DECLARE_PCI_FIXUP_RESUME ( PCI_VENDOR_ID_CYRIX , PCI_DEVICE_ID_CYRIX_5530_LEGACY ,
pci_early_fixup_cyrix_5530 ) ;
2007-05-23 14:50:02 -07:00
/*
* Siemens Nixdorf AG FSC Multiprocessor Interrupt Controller :
* prevent update of the BAR0 , which doesn ' t look like a normal BAR .
*/
2012-12-21 14:02:53 -08:00
static void pci_siemens_interrupt_controller ( struct pci_dev * dev )
2007-05-23 14:50:02 -07:00
{
dev - > resource [ 0 ] . flags | = IORESOURCE_PCI_FIXED ;
}
DECLARE_PCI_FIXUP_HEADER ( PCI_VENDOR_ID_SIEMENS , 0x0015 ,
pci_siemens_interrupt_controller ) ;
2008-02-15 01:32:50 -08:00
2008-09-12 11:45:22 -06:00
/*
* SB600 : Disable BAR1 on device 14.0 to avoid HPET resources from
* confusing the PCI engine :
*/
static void sb600_disable_hpet_bar ( struct pci_dev * dev )
{
u8 val ;
/*
* The SB600 and SB700 both share the same device
* ID , but the PM register 0x55 does something different
* for the SB700 , so make sure we are dealing with the
* SB600 before touching the bit :
*/
pci_read_config_byte ( dev , 0x08 , & val ) ;
if ( val < 0x2F ) {
outb ( 0x55 , 0xCD6 ) ;
val = inb ( 0xCD7 ) ;
/* Set bit 7 in PM register 0x55 */
outb ( 0x55 , 0xCD6 ) ;
outb ( val | 0x80 , 0xCD7 ) ;
}
}
DECLARE_PCI_FIXUP_EARLY ( PCI_VENDOR_ID_ATI , 0x4385 , sb600_disable_hpet_bar ) ;
2012-05-15 18:44:15 +01:00
x86/PCI: Mark ATI SBx00 HPET BAR as IORESOURCE_PCI_FIXED
Bodo reported that on the Asrock M3A UCC, v3.12.6 hangs during boot unless
he uses "pci=nocrs". This regression was caused by 7bc5e3f2be32 ("x86/PCI:
use host bridge _CRS info by default on 2008 and newer machines"), which
appeared in v2.6.34.
The reason is that the HPET address appears in a PCI device BAR, and this
address is not contained in any of the host bridge windows. Linux moves
the PCI BAR into a window, but the original address was published via the
HPET table and an ACPI device, so changing the BAR is a bad idea. Here's
the dmesg info:
ACPI: HPET id: 0x43538301 base: 0xfed00000
pci_root PNP0A03:00: host bridge window [mem 0xd0000000-0xdfffffff]
pci_root PNP0A03:00: host bridge window [mem 0xf0000000-0xfebfffff]
pci 0000:00:14.0: [1002:4385] type 0 class 0x000c05
pci 0000:00:14.0: reg 14: [mem 0xfed00000-0xfed003ff]
hpet0: at MMIO 0xfed00000, IRQs 2, 8, 0, 0
pnp 00:06: Plug and Play ACPI device, IDs PNP0103 (active)
pnp 00:06: [mem 0xfed00000-0xfed003ff]
When we notice the BAR is not in a host bridge window, we try to move it,
but that causes a hang shortly thereafter:
pci 0000:00:14.0: no compatible bridge window for [mem 0xfed00000-0xfed003ff]
pci 0000:00:14.0: BAR 1: assigned [mem 0xf0000000-0xf00003ff]
This patch marks the BAR as IORESOURCE_PCI_FIXED to prevent Linux from
moving it. This depends on a previous patch ("x86/PCI: Don't try to move
IORESOURCE_PCI_FIXED resources") to check for this flag when
pci_claim_resource() fails.
Link: https://bugzilla.kernel.org/show_bug.cgi?id=68591
Reported-and-tested-by: Bodo Eggert <7eggert@gmx.de>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
2014-04-14 15:35:21 -06:00
# ifdef CONFIG_HPET_TIMER
static void sb600_hpet_quirk ( struct pci_dev * dev )
{
struct resource * r = & dev - > resource [ 1 ] ;
if ( r - > flags & IORESOURCE_MEM & & r - > start = = hpet_address ) {
r - > flags | = IORESOURCE_PCI_FIXED ;
dev_info ( & dev - > dev , " reg 0x14 contains HPET; making it immovable \n " ) ;
}
}
DECLARE_PCI_FIXUP_HEADER ( PCI_VENDOR_ID_ATI , 0x4385 , sb600_hpet_quirk ) ;
# endif
2012-05-15 18:44:15 +01:00
/*
* Twinhead H12Y needs us to block out a region otherwise we map devices
* there and any access kills the box .
*
* See : https : //bugzilla.kernel.org/show_bug.cgi?id=10231
*
* Match off the LPC and svid / sdid ( older kernels lose the bridge subvendor )
*/
2012-12-21 14:02:53 -08:00
static void twinhead_reserve_killing_zone ( struct pci_dev * dev )
2012-05-15 18:44:15 +01:00
{
if ( dev - > subsystem_vendor = = 0x14FF & & dev - > subsystem_device = = 0xA003 ) {
pr_info ( " Reserving memory on Twinhead H12Y \n " ) ;
request_mem_region ( 0xFFB00000 , 0x100000 , " twinhead " ) ;
}
}
DECLARE_PCI_FIXUP_HEADER ( PCI_VENDOR_ID_INTEL , 0x27B9 , twinhead_reserve_killing_zone ) ;