diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_device.c')
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 31 | 
1 files changed, 31 insertions, 0 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 620afd75dae7..b9d50cb6c236 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -34,6 +34,7 @@  #include <linux/pci.h>  #include <linux/devcoredump.h>  #include <generated/utsrelease.h> +#include <linux/pci-p2pdma.h>  #include <drm/drm_atomic_helper.h>  #include <drm/drm_probe_helper.h> @@ -5499,6 +5500,36 @@ static void amdgpu_device_get_pcie_info(struct amdgpu_device *adev)  	}  } +/** + * amdgpu_device_is_peer_accessible - Check peer access through PCIe BAR + * + * @adev: amdgpu_device pointer + * @peer_adev: amdgpu_device pointer for peer device trying to access @adev + * + * Return true if @peer_adev can access (DMA) @adev through the PCIe + * BAR, i.e. @adev is "large BAR" and the BAR matches the DMA mask of + * @peer_adev. + */ +bool amdgpu_device_is_peer_accessible(struct amdgpu_device *adev, +				      struct amdgpu_device *peer_adev) +{ +#ifdef CONFIG_HSA_AMD_P2P +	uint64_t address_mask = peer_adev->dev->dma_mask ? +		~*peer_adev->dev->dma_mask : ~((1ULL << 32) - 1); +	resource_size_t aper_limit = +		adev->gmc.aper_base + adev->gmc.aper_size - 1; +	bool p2p_access = !(pci_p2pdma_distance_many(adev->pdev, +					&peer_adev->dev, 1, true) < 0); + +	return pcie_p2p && p2p_access && (adev->gmc.visible_vram_size && +		adev->gmc.real_vram_size == adev->gmc.visible_vram_size && +		!(adev->gmc.aper_base & address_mask || +		  aper_limit & address_mask)); +#else +	return false; +#endif +} +  int amdgpu_device_baco_enter(struct drm_device *dev)  {  	struct amdgpu_device *adev = drm_to_adev(dev);  | 
