Skip to content

Commit cacf994

Browse files
mikelrbjorn-helgaas
authored andcommitted
PCI: Add AMD RS690 quirk to enable 64-bit DMA
Although the AMD RS690 chipset has 64-bit DMA support, BIOS implementations sometimes fail to configure the memory limit registers correctly. The Acer F690GVM mainboard uses this chipset and a Marvell 88E8056 NIC. The sky2 driver programs the NIC to use 64-bit DMA, which will not work: sky2 0000:02:00.0: error interrupt status=0x8 sky2 0000:02:00.0 eth0: tx timeout sky2 0000:02:00.0 eth0: transmit ring 0 .. 22 report=0 done=0 Other drivers required by this mainboard either don't support 64-bit DMA, or have it disabled using driver specific quirks. For example, the ahci driver has quirks to enable or disable 64-bit DMA depending on the BIOS version (see ahci_sb600_enable_64bit() in ahci.c). This ahci quirk matches against the SB600 SATA controller, but the real issue is almost certainly with the RS690 PCI host that it was commonly attached to. To avoid this issue in all drivers with 64-bit DMA support, fix the configuration of the PCI host. If the kernel is aware of physical memory above 4GB, but the BIOS never configured the PCI host with this information, update the registers with our values. [bhelgaas: drop PCI_DEVICE_ID_ATI_RS690 definition] Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Mikel Rychliski <[email protected]> Signed-off-by: Bjorn Helgaas <[email protected]>
1 parent db2f77e commit cacf994

File tree

1 file changed

+44
-0
lines changed

1 file changed

+44
-0
lines changed

arch/x86/pci/fixup.c

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -779,4 +779,48 @@ DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, 0x1571, pci_amd_enable_64bit_bar);
779779
DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, 0x15b1, pci_amd_enable_64bit_bar);
780780
DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, 0x1601, pci_amd_enable_64bit_bar);
781781

782+
#define RS690_LOWER_TOP_OF_DRAM2 0x30
783+
#define RS690_LOWER_TOP_OF_DRAM2_VALID 0x1
784+
#define RS690_UPPER_TOP_OF_DRAM2 0x31
785+
#define RS690_HTIU_NB_INDEX 0xA8
786+
#define RS690_HTIU_NB_INDEX_WR_ENABLE 0x100
787+
#define RS690_HTIU_NB_DATA 0xAC
788+
789+
/*
790+
* Some BIOS implementations support RAM above 4GB, but do not configure the
791+
* PCI host to respond to bus master accesses for these addresses. These
792+
* implementations set the TOP_OF_DRAM_SLOT1 register correctly, so PCI DMA
793+
* works as expected for addresses below 4GB.
794+
*
795+
* Reference: "AMD RS690 ASIC Family Register Reference Guide" (pg. 2-57)
796+
* https://www.amd.com/system/files/TechDocs/43372_rs690_rrg_3.00o.pdf
797+
*/
798+
static void rs690_fix_64bit_dma(struct pci_dev *pdev)
799+
{
800+
u32 val = 0;
801+
phys_addr_t top_of_dram = __pa(high_memory - 1) + 1;
802+
803+
if (top_of_dram <= (1ULL << 32))
804+
return;
805+
806+
pci_write_config_dword(pdev, RS690_HTIU_NB_INDEX,
807+
RS690_LOWER_TOP_OF_DRAM2);
808+
pci_read_config_dword(pdev, RS690_HTIU_NB_DATA, &val);
809+
810+
if (val)
811+
return;
812+
813+
pci_info(pdev, "Adjusting top of DRAM to %pa for 64-bit DMA support\n", &top_of_dram);
814+
815+
pci_write_config_dword(pdev, RS690_HTIU_NB_INDEX,
816+
RS690_UPPER_TOP_OF_DRAM2 | RS690_HTIU_NB_INDEX_WR_ENABLE);
817+
pci_write_config_dword(pdev, RS690_HTIU_NB_DATA, top_of_dram >> 32);
818+
819+
pci_write_config_dword(pdev, RS690_HTIU_NB_INDEX,
820+
RS690_LOWER_TOP_OF_DRAM2 | RS690_HTIU_NB_INDEX_WR_ENABLE);
821+
pci_write_config_dword(pdev, RS690_HTIU_NB_DATA,
822+
top_of_dram | RS690_LOWER_TOP_OF_DRAM2_VALID);
823+
}
824+
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x7910, rs690_fix_64bit_dma);
825+
782826
#endif

0 commit comments

Comments
 (0)