diff options
Diffstat (limited to 'arch/x86/kernel/amd_iommu_init.c')
| -rw-r--r-- | arch/x86/kernel/amd_iommu_init.c | 67 | 
1 files changed, 45 insertions, 22 deletions
diff --git a/arch/x86/kernel/amd_iommu_init.c b/arch/x86/kernel/amd_iommu_init.c index 3cc63e2b8dd..5a170cbbbed 100644 --- a/arch/x86/kernel/amd_iommu_init.c +++ b/arch/x86/kernel/amd_iommu_init.c @@ -632,6 +632,13 @@ static void __init init_iommu_from_pci(struct amd_iommu *iommu)  	iommu->last_device = calc_devid(MMIO_GET_BUS(range),  					MMIO_GET_LD(range));  	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;  	/* -	 * 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 @@ -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   * they have been initialized @@ -1126,6 +1147,8 @@ static void enable_iommus(void)  	for_each_iommu(iommu) {  		iommu_disable(iommu); +		iommu_apply_quirks(iommu); +		iommu_init_flags(iommu);  		iommu_set_device_table(iommu);  		iommu_enable_command_buffer(iommu);  		iommu_enable_event_buffer(iommu);  |