|
@@ -632,6 +632,13 @@ static void __init init_iommu_from_pci(struct amd_iommu *iommu)
|
|
iommu->last_device = calc_devid(MMIO_GET_BUS(range),
|
|
iommu->last_device = calc_devid(MMIO_GET_BUS(range),
|
|
MMIO_GET_LD(range));
|
|
MMIO_GET_LD(range));
|
|
iommu->evt_msi_num = MMIO_MSI_NUM(misc);
|
|
iommu->evt_msi_num = MMIO_MSI_NUM(misc);
|
|
|
|
+
|
|
|
|
+ if (is_rd890_iommu(iommu->dev)) {
|
|
|
|
+ pci_read_config_dword(iommu->dev, 0xf0, &iommu->cache_cfg[0]);
|
|
|
|
+ pci_read_config_dword(iommu->dev, 0xf4, &iommu->cache_cfg[1]);
|
|
|
|
+ pci_read_config_dword(iommu->dev, 0xf8, &iommu->cache_cfg[2]);
|
|
|
|
+ pci_read_config_dword(iommu->dev, 0xfc, &iommu->cache_cfg[3]);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
/*
|
|
@@ -649,29 +656,9 @@ static void __init init_iommu_from_acpi(struct amd_iommu *iommu,
|
|
struct ivhd_entry *e;
|
|
struct ivhd_entry *e;
|
|
|
|
|
|
/*
|
|
/*
|
|
- * First set the recommended feature enable bits from ACPI
|
|
|
|
- * into the IOMMU control registers
|
|
|
|
|
|
+ * First save the recommended feature enable bits from ACPI
|
|
*/
|
|
*/
|
|
- h->flags & IVHD_FLAG_HT_TUN_EN_MASK ?
|
|
|
|
- iommu_feature_enable(iommu, CONTROL_HT_TUN_EN) :
|
|
|
|
- iommu_feature_disable(iommu, CONTROL_HT_TUN_EN);
|
|
|
|
-
|
|
|
|
- h->flags & IVHD_FLAG_PASSPW_EN_MASK ?
|
|
|
|
- iommu_feature_enable(iommu, CONTROL_PASSPW_EN) :
|
|
|
|
- iommu_feature_disable(iommu, CONTROL_PASSPW_EN);
|
|
|
|
-
|
|
|
|
- h->flags & IVHD_FLAG_RESPASSPW_EN_MASK ?
|
|
|
|
- iommu_feature_enable(iommu, CONTROL_RESPASSPW_EN) :
|
|
|
|
- iommu_feature_disable(iommu, CONTROL_RESPASSPW_EN);
|
|
|
|
-
|
|
|
|
- h->flags & IVHD_FLAG_ISOC_EN_MASK ?
|
|
|
|
- iommu_feature_enable(iommu, CONTROL_ISOC_EN) :
|
|
|
|
- iommu_feature_disable(iommu, CONTROL_ISOC_EN);
|
|
|
|
-
|
|
|
|
- /*
|
|
|
|
- * make IOMMU memory accesses cache coherent
|
|
|
|
- */
|
|
|
|
- iommu_feature_enable(iommu, CONTROL_COHERENT_EN);
|
|
|
|
|
|
+ iommu->acpi_flags = h->flags;
|
|
|
|
|
|
/*
|
|
/*
|
|
* Done. Now parse the device entries
|
|
* Done. Now parse the device entries
|
|
@@ -1116,6 +1103,40 @@ static void init_device_table(void)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static void iommu_init_flags(struct amd_iommu *iommu)
|
|
|
|
+{
|
|
|
|
+ iommu->acpi_flags & IVHD_FLAG_HT_TUN_EN_MASK ?
|
|
|
|
+ iommu_feature_enable(iommu, CONTROL_HT_TUN_EN) :
|
|
|
|
+ iommu_feature_disable(iommu, CONTROL_HT_TUN_EN);
|
|
|
|
+
|
|
|
|
+ iommu->acpi_flags & IVHD_FLAG_PASSPW_EN_MASK ?
|
|
|
|
+ iommu_feature_enable(iommu, CONTROL_PASSPW_EN) :
|
|
|
|
+ iommu_feature_disable(iommu, CONTROL_PASSPW_EN);
|
|
|
|
+
|
|
|
|
+ iommu->acpi_flags & IVHD_FLAG_RESPASSPW_EN_MASK ?
|
|
|
|
+ iommu_feature_enable(iommu, CONTROL_RESPASSPW_EN) :
|
|
|
|
+ iommu_feature_disable(iommu, CONTROL_RESPASSPW_EN);
|
|
|
|
+
|
|
|
|
+ iommu->acpi_flags & IVHD_FLAG_ISOC_EN_MASK ?
|
|
|
|
+ iommu_feature_enable(iommu, CONTROL_ISOC_EN) :
|
|
|
|
+ iommu_feature_disable(iommu, CONTROL_ISOC_EN);
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * make IOMMU memory accesses cache coherent
|
|
|
|
+ */
|
|
|
|
+ iommu_feature_enable(iommu, CONTROL_COHERENT_EN);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static void iommu_apply_quirks(struct amd_iommu *iommu)
|
|
|
|
+{
|
|
|
|
+ if (is_rd890_iommu(iommu->dev)) {
|
|
|
|
+ pci_write_config_dword(iommu->dev, 0xf0, iommu->cache_cfg[0]);
|
|
|
|
+ pci_write_config_dword(iommu->dev, 0xf4, iommu->cache_cfg[1]);
|
|
|
|
+ pci_write_config_dword(iommu->dev, 0xf8, iommu->cache_cfg[2]);
|
|
|
|
+ pci_write_config_dword(iommu->dev, 0xfc, iommu->cache_cfg[3]);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
/*
|
|
/*
|
|
* This function finally enables all IOMMUs found in the system after
|
|
* This function finally enables all IOMMUs found in the system after
|
|
* they have been initialized
|
|
* they have been initialized
|
|
@@ -1126,6 +1147,8 @@ static void enable_iommus(void)
|
|
|
|
|
|
for_each_iommu(iommu) {
|
|
for_each_iommu(iommu) {
|
|
iommu_disable(iommu);
|
|
iommu_disable(iommu);
|
|
|
|
+ iommu_apply_quirks(iommu);
|
|
|
|
+ iommu_init_flags(iommu);
|
|
iommu_set_device_table(iommu);
|
|
iommu_set_device_table(iommu);
|
|
iommu_enable_command_buffer(iommu);
|
|
iommu_enable_command_buffer(iommu);
|
|
iommu_enable_event_buffer(iommu);
|
|
iommu_enable_event_buffer(iommu);
|