Commit e7df065a authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge branch 'drm-next-4.21' of git://people.freedesktop.org/~agd5f/linux into drm-next



[airlied: make etnaviv build again]

amdgpu:
- DC trace support
- More DC documentation
- XGMI hive reset support
- Rework IH interaction with KFD
- Misc fixes and cleanups
- Powerplay updates for newer polaris variants
- Add cursor plane update fast path
- Enable gpu reset by default on CI parts
- Fix config with KFD/HSA not enabled

amdkfd:
- Limit vram overcommit
- dmabuf support
- Support for doorbell BOs

ttm:
- Support for simultaneous submissions to multiple engines

scheduler:
- Add helpers for hw with preemption support

Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
From: Alex Deucher <alexdeucher@gmail.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20181207233119.16861-1-alexander.deucher@amd.com
parents e69aa5f9 674e78ac
Loading
Loading
Loading
Loading
+7 −3
Original line number Diff line number Diff line
@@ -82,6 +82,7 @@
#include "amdgpu_bo_list.h"
#include "amdgpu_gem.h"
#include "amdgpu_doorbell.h"
#include "amdgpu_amdkfd.h"

#define MAX_GPU_INSTANCE		16

@@ -163,6 +164,7 @@ extern int amdgpu_si_support;
extern int amdgpu_cik_support;
#endif

#define AMDGPU_VM_MAX_NUM_CTX			4096
#define AMDGPU_SG_THRESHOLD			(256*1024*1024)
#define AMDGPU_DEFAULT_GTT_SIZE_MB		3072ULL /* 3GB by default */
#define AMDGPU_WAIT_IDLE_TIMEOUT_IN_MS	        3000
@@ -862,6 +864,9 @@ struct amdgpu_device {
	/* GDS */
	struct amdgpu_gds		gds;

	/* KFD */
	struct amdgpu_kfd_dev		kfd;

	/* display related functionality */
	struct amdgpu_display_manager dm;

@@ -875,9 +880,6 @@ struct amdgpu_device {
	atomic64_t visible_pin_size;
	atomic64_t gart_pin_size;

	/* amdkfd interface */
	struct kfd_dev          *kfd;

	/* soc15 register offset based on ip, instance and  segment */
	uint32_t 		*reg_offset[MAX_HWIP][HWIP_MAX_INSTANCE];

@@ -910,7 +912,9 @@ struct amdgpu_device {
	bool                            in_gpu_reset;
	struct mutex  lock_reset;
	struct amdgpu_doorbell_index doorbell_index;

	int asic_reset_res;
	struct work_struct		xgmi_reset_work;
};

static inline struct amdgpu_device *amdgpu_ttm_adev(struct ttm_bo_device *bdev)
+1 −2
Original line number Diff line number Diff line
@@ -886,6 +886,5 @@ void amdgpu_acpi_get_backlight_caps(struct amdgpu_device *adev,
void amdgpu_acpi_fini(struct amdgpu_device *adev)
{
	unregister_acpi_notifier(&adev->acpi_nb);
	if (adev->atif)
	kfree(adev->atif);
}
+91 −20
Original line number Diff line number Diff line
@@ -26,15 +26,26 @@
#include "amdgpu.h"
#include "amdgpu_gfx.h"
#include <linux/module.h>
#include <linux/dma-buf.h>

const struct kgd2kfd_calls *kgd2kfd;

static const unsigned int compute_vmid_bitmap = 0xFF00;

/* Total memory size in system memory and all GPU VRAM. Used to
 * estimate worst case amount of memory to reserve for page tables
 */
uint64_t amdgpu_amdkfd_total_mem_size;

int amdgpu_amdkfd_init(void)
{
	struct sysinfo si;
	int ret;

	si_meminfo(&si);
	amdgpu_amdkfd_total_mem_size = si.totalram - si.totalhigh;
	amdgpu_amdkfd_total_mem_size *= si.mem_unit;

#ifdef CONFIG_HSA_AMD
	ret = kgd2kfd_init(KFD_INTERFACE_VERSION, &kgd2kfd);
	if (ret)
@@ -87,8 +98,11 @@ void amdgpu_amdkfd_device_probe(struct amdgpu_device *adev)
		return;
	}

	adev->kfd = kgd2kfd->probe((struct kgd_dev *)adev,
	adev->kfd.dev = kgd2kfd->probe((struct kgd_dev *)adev,
				       adev->pdev, kfd2kgd);

	if (adev->kfd.dev)
		amdgpu_amdkfd_total_mem_size += adev->gmc.real_vram_size;
}

/**
@@ -128,7 +142,8 @@ void amdgpu_amdkfd_device_init(struct amdgpu_device *adev)
{
	int i, n;
	int last_valid_bit;
	if (adev->kfd) {

	if (adev->kfd.dev) {
		struct kgd2kfd_shared_resources gpu_resources = {
			.compute_vmid_bitmap = compute_vmid_bitmap,
			.num_pipe_per_mec = adev->gfx.mec.num_pipe_per_mec,
@@ -167,7 +182,7 @@ void amdgpu_amdkfd_device_init(struct amdgpu_device *adev)
				&gpu_resources.doorbell_start_offset);

		if (adev->asic_type < CHIP_VEGA10) {
			kgd2kfd->device_init(adev->kfd, &gpu_resources);
			kgd2kfd->device_init(adev->kfd.dev, &gpu_resources);
			return;
		}

@@ -196,37 +211,37 @@ void amdgpu_amdkfd_device_init(struct amdgpu_device *adev)
		gpu_resources.reserved_doorbell_mask = 0x1e0;
		gpu_resources.reserved_doorbell_val  = 0x0e0;

		kgd2kfd->device_init(adev->kfd, &gpu_resources);
		kgd2kfd->device_init(adev->kfd.dev, &gpu_resources);
	}
}

void amdgpu_amdkfd_device_fini(struct amdgpu_device *adev)
{
	if (adev->kfd) {
		kgd2kfd->device_exit(adev->kfd);
		adev->kfd = NULL;
	if (adev->kfd.dev) {
		kgd2kfd->device_exit(adev->kfd.dev);
		adev->kfd.dev = NULL;
	}
}

void amdgpu_amdkfd_interrupt(struct amdgpu_device *adev,
		const void *ih_ring_entry)
{
	if (adev->kfd)
		kgd2kfd->interrupt(adev->kfd, ih_ring_entry);
	if (adev->kfd.dev)
		kgd2kfd->interrupt(adev->kfd.dev, ih_ring_entry);
}

void amdgpu_amdkfd_suspend(struct amdgpu_device *adev)
{
	if (adev->kfd)
		kgd2kfd->suspend(adev->kfd);
	if (adev->kfd.dev)
		kgd2kfd->suspend(adev->kfd.dev);
}

int amdgpu_amdkfd_resume(struct amdgpu_device *adev)
{
	int r = 0;

	if (adev->kfd)
		r = kgd2kfd->resume(adev->kfd);
	if (adev->kfd.dev)
		r = kgd2kfd->resume(adev->kfd.dev);

	return r;
}
@@ -235,8 +250,8 @@ int amdgpu_amdkfd_pre_reset(struct amdgpu_device *adev)
{
	int r = 0;

	if (adev->kfd)
		r = kgd2kfd->pre_reset(adev->kfd);
	if (adev->kfd.dev)
		r = kgd2kfd->pre_reset(adev->kfd.dev);

	return r;
}
@@ -245,8 +260,8 @@ int amdgpu_amdkfd_post_reset(struct amdgpu_device *adev)
{
	int r = 0;

	if (adev->kfd)
		r = kgd2kfd->post_reset(adev->kfd);
	if (adev->kfd.dev)
		r = kgd2kfd->post_reset(adev->kfd.dev);

	return r;
}
@@ -419,6 +434,62 @@ void amdgpu_amdkfd_get_cu_info(struct kgd_dev *kgd, struct kfd_cu_info *cu_info)
	cu_info->lds_size = acu_info.lds_size;
}

int amdgpu_amdkfd_get_dmabuf_info(struct kgd_dev *kgd, int dma_buf_fd,
				  struct kgd_dev **dma_buf_kgd,
				  uint64_t *bo_size, void *metadata_buffer,
				  size_t buffer_size, uint32_t *metadata_size,
				  uint32_t *flags)
{
	struct amdgpu_device *adev = (struct amdgpu_device *)kgd;
	struct dma_buf *dma_buf;
	struct drm_gem_object *obj;
	struct amdgpu_bo *bo;
	uint64_t metadata_flags;
	int r = -EINVAL;

	dma_buf = dma_buf_get(dma_buf_fd);
	if (IS_ERR(dma_buf))
		return PTR_ERR(dma_buf);

	if (dma_buf->ops != &amdgpu_dmabuf_ops)
		/* Can't handle non-graphics buffers */
		goto out_put;

	obj = dma_buf->priv;
	if (obj->dev->driver != adev->ddev->driver)
		/* Can't handle buffers from different drivers */
		goto out_put;

	adev = obj->dev->dev_private;
	bo = gem_to_amdgpu_bo(obj);
	if (!(bo->preferred_domains & (AMDGPU_GEM_DOMAIN_VRAM |
				    AMDGPU_GEM_DOMAIN_GTT)))
		/* Only VRAM and GTT BOs are supported */
		goto out_put;

	r = 0;
	if (dma_buf_kgd)
		*dma_buf_kgd = (struct kgd_dev *)adev;
	if (bo_size)
		*bo_size = amdgpu_bo_size(bo);
	if (metadata_size)
		*metadata_size = bo->metadata_size;
	if (metadata_buffer)
		r = amdgpu_bo_get_metadata(bo, metadata_buffer, buffer_size,
					   metadata_size, &metadata_flags);
	if (flags) {
		*flags = (bo->preferred_domains & AMDGPU_GEM_DOMAIN_VRAM) ?
			ALLOC_MEM_FLAGS_VRAM : ALLOC_MEM_FLAGS_GTT;

		if (bo->flags & AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED)
			*flags |= ALLOC_MEM_FLAGS_PUBLIC;
	}

out_put:
	dma_buf_put(dma_buf);
	return r;
}

uint64_t amdgpu_amdkfd_get_vram_usage(struct kgd_dev *kgd)
{
	struct amdgpu_device *adev = (struct amdgpu_device *)kgd;
@@ -501,7 +572,7 @@ void amdgpu_amdkfd_set_compute_idle(struct kgd_dev *kgd, bool idle)

bool amdgpu_amdkfd_is_kfd_vmid(struct amdgpu_device *adev, u32 vmid)
{
	if (adev->kfd) {
	if (adev->kfd.dev) {
		if ((1 << vmid) & compute_vmid_bitmap)
			return true;
	}
@@ -515,7 +586,7 @@ bool amdkfd_fence_check_mm(struct dma_fence *f, struct mm_struct *mm)
	return false;
}

void amdgpu_amdkfd_unreserve_system_memory_limit(struct amdgpu_bo *bo)
void amdgpu_amdkfd_unreserve_memory_limit(struct amdgpu_bo *bo)
{
}

+18 −2
Original line number Diff line number Diff line
@@ -27,7 +27,6 @@

#include <linux/types.h>
#include <linux/mm.h>
#include <linux/mmu_context.h>
#include <linux/workqueue.h>
#include <kgd_kfd_interface.h>
#include <drm/ttm/ttm_execbuf_util.h>
@@ -35,6 +34,7 @@
#include "amdgpu_vm.h"

extern const struct kgd2kfd_calls *kgd2kfd;
extern uint64_t amdgpu_amdkfd_total_mem_size;

struct amdgpu_device;

@@ -77,6 +77,11 @@ struct amdgpu_amdkfd_fence {
	char timeline_name[TASK_COMM_LEN];
};

struct amdgpu_kfd_dev {
	struct kfd_dev *dev;
	uint64_t vram_used;
};

struct amdgpu_amdkfd_fence *amdgpu_amdkfd_fence_create(u64 context,
						       struct mm_struct *mm);
bool amdkfd_fence_check_mm(struct dma_fence *f, struct mm_struct *mm);
@@ -144,6 +149,11 @@ uint64_t amdgpu_amdkfd_get_gpu_clock_counter(struct kgd_dev *kgd);

uint32_t amdgpu_amdkfd_get_max_engine_clock_in_mhz(struct kgd_dev *kgd);
void amdgpu_amdkfd_get_cu_info(struct kgd_dev *kgd, struct kfd_cu_info *cu_info);
int amdgpu_amdkfd_get_dmabuf_info(struct kgd_dev *kgd, int dma_buf_fd,
				  struct kgd_dev **dmabuf_kgd,
				  uint64_t *bo_size, void *metadata_buffer,
				  size_t buffer_size, uint32_t *metadata_size,
				  uint32_t *flags);
uint64_t amdgpu_amdkfd_get_vram_usage(struct kgd_dev *kgd);
uint64_t amdgpu_amdkfd_get_hive_id(struct kgd_dev *kgd);

@@ -195,7 +205,13 @@ int amdgpu_amdkfd_gpuvm_restore_process_bos(void *process_info,
int amdgpu_amdkfd_gpuvm_get_vm_fault_info(struct kgd_dev *kgd,
					      struct kfd_vm_fault_info *info);

int amdgpu_amdkfd_gpuvm_import_dmabuf(struct kgd_dev *kgd,
				      struct dma_buf *dmabuf,
				      uint64_t va, void *vm,
				      struct kgd_mem **mem, uint64_t *size,
				      uint64_t *mmap_offset);

void amdgpu_amdkfd_gpuvm_init_mem_limits(void);
void amdgpu_amdkfd_unreserve_system_memory_limit(struct amdgpu_bo *bo);
void amdgpu_amdkfd_unreserve_memory_limit(struct amdgpu_bo *bo);

#endif /* AMDGPU_AMDKFD_H_INCLUDED */
+1 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@
#include <linux/fdtable.h>
#include <linux/uaccess.h>
#include <linux/firmware.h>
#include <linux/mmu_context.h>
#include <drm/drmP.h>
#include "amdgpu.h"
#include "amdgpu_amdkfd.h"
Loading