diff options
Diffstat (limited to 'drivers/iommu/amd_iommu_init.c')
-rw-r--r-- | drivers/iommu/amd_iommu_init.c | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c index 81837b0710a9..faf10ba1ed9a 100644 --- a/drivers/iommu/amd_iommu_init.c +++ b/drivers/iommu/amd_iommu_init.c | |||
@@ -975,6 +975,38 @@ static void __init free_iommu_all(void) | |||
975 | } | 975 | } |
976 | 976 | ||
977 | /* | 977 | /* |
978 | * Family15h Model 10h-1fh erratum 746 (IOMMU Logging May Stall Translations) | ||
979 | * Workaround: | ||
980 | * BIOS should disable L2B micellaneous clock gating by setting | ||
981 | * L2_L2B_CK_GATE_CONTROL[CKGateL2BMiscDisable](D0F2xF4_x90[2]) = 1b | ||
982 | */ | ||
983 | static void __init amd_iommu_erratum_746_workaround(struct amd_iommu *iommu) | ||
984 | { | ||
985 | u32 value; | ||
986 | |||
987 | if ((boot_cpu_data.x86 != 0x15) || | ||
988 | (boot_cpu_data.x86_model < 0x10) || | ||
989 | (boot_cpu_data.x86_model > 0x1f)) | ||
990 | return; | ||
991 | |||
992 | pci_write_config_dword(iommu->dev, 0xf0, 0x90); | ||
993 | pci_read_config_dword(iommu->dev, 0xf4, &value); | ||
994 | |||
995 | if (value & BIT(2)) | ||
996 | return; | ||
997 | |||
998 | /* Select NB indirect register 0x90 and enable writing */ | ||
999 | pci_write_config_dword(iommu->dev, 0xf0, 0x90 | (1 << 8)); | ||
1000 | |||
1001 | pci_write_config_dword(iommu->dev, 0xf4, value | 0x4); | ||
1002 | pr_info("AMD-Vi: Applying erratum 746 workaround for IOMMU at %s\n", | ||
1003 | dev_name(&iommu->dev->dev)); | ||
1004 | |||
1005 | /* Clear the enable writing bit */ | ||
1006 | pci_write_config_dword(iommu->dev, 0xf0, 0x90); | ||
1007 | } | ||
1008 | |||
1009 | /* | ||
978 | * This function clues the initialization function for one IOMMU | 1010 | * This function clues the initialization function for one IOMMU |
979 | * together and also allocates the command buffer and programs the | 1011 | * together and also allocates the command buffer and programs the |
980 | * hardware. It does NOT enable the IOMMU. This is done afterwards. | 1012 | * hardware. It does NOT enable the IOMMU. This is done afterwards. |
@@ -1172,6 +1204,8 @@ static int iommu_init_pci(struct amd_iommu *iommu) | |||
1172 | iommu->stored_l2[i] = iommu_read_l2(iommu, i); | 1204 | iommu->stored_l2[i] = iommu_read_l2(iommu, i); |
1173 | } | 1205 | } |
1174 | 1206 | ||
1207 | amd_iommu_erratum_746_workaround(iommu); | ||
1208 | |||
1175 | return pci_enable_device(iommu->dev); | 1209 | return pci_enable_device(iommu->dev); |
1176 | } | 1210 | } |
1177 | 1211 | ||