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

Merge tag 'amd-drm-next-5.9-2020-07-17' of git://people.freedesktop.org/~agd5f/linux into drm-next

amd-drm-next-5.9-2020-07-17:

amdgpu:
- SI UVD/VCE clock support
- Updates for Sienna Cichlid
- Expose drm rotation property
- Atomfirmware updates for renoir
- updates to GPUVM hub handling for different register layouts
- swSMU restructuring and cleanups
- RAS fixes
- DC fixes
- mode1 reset support for Sienna Cichlid
- Add support for Navy Flounder GPUs

amdkfd:
- Add SMI events watch interface

UAPI:
- Add amdkfd SMI events watch interface
  Userspace which uses this interface:
  https://github.com/RadeonOpenCompute/rocm_smi_lib/commit/2235ede34c456f1c7d3490f6fe74825d442d272e



Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
From: Alex Deucher <alexdeucher@gmail.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200717132022.4014-1-alexander.deucher@amd.com
parents 959ed538 6e14adea
Loading
Loading
Loading
Loading
+19 −9
Original line number Diff line number Diff line
@@ -193,6 +193,7 @@ static const bool debug_evictions; /* = false */
#endif

extern int amdgpu_tmz;
extern int amdgpu_reset_method;

#ifdef CONFIG_DRM_AMDGPU_SI
extern int amdgpu_si_support;
@@ -1010,9 +1011,9 @@ int amdgpu_gpu_wait_for_idle(struct amdgpu_device *adev);

void amdgpu_device_vram_access(struct amdgpu_device *adev, loff_t pos,
			       uint32_t *buf, size_t size, bool write);
uint32_t amdgpu_device_rreg(struct amdgpu_device *adev, uint32_t reg,
uint32_t amdgpu_mm_rreg(struct amdgpu_device *adev, uint32_t reg,
			uint32_t acc_flags);
void amdgpu_device_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v,
void amdgpu_mm_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v,
		    uint32_t acc_flags);
void amdgpu_mm_wreg_mmio_rlc(struct amdgpu_device *adev, uint32_t reg, uint32_t v,
		    uint32_t acc_flags);
@@ -1032,8 +1033,8 @@ int emu_soc_asic_init(struct amdgpu_device *adev);
 */
#define AMDGPU_REGS_NO_KIQ    (1<<1)

#define RREG32_NO_KIQ(reg) amdgpu_device_rreg(adev, (reg), AMDGPU_REGS_NO_KIQ)
#define WREG32_NO_KIQ(reg, v) amdgpu_device_wreg(adev, (reg), (v), AMDGPU_REGS_NO_KIQ)
#define RREG32_NO_KIQ(reg) amdgpu_mm_rreg(adev, (reg), AMDGPU_REGS_NO_KIQ)
#define WREG32_NO_KIQ(reg, v) amdgpu_mm_wreg(adev, (reg), (v), AMDGPU_REGS_NO_KIQ)

#define RREG32_KIQ(reg) amdgpu_kiq_rreg(adev, (reg))
#define WREG32_KIQ(reg, v) amdgpu_kiq_wreg(adev, (reg), (v))
@@ -1041,9 +1042,9 @@ int emu_soc_asic_init(struct amdgpu_device *adev);
#define RREG8(reg) amdgpu_mm_rreg8(adev, (reg))
#define WREG8(reg, v) amdgpu_mm_wreg8(adev, (reg), (v))

#define RREG32(reg) amdgpu_device_rreg(adev, (reg), 0)
#define DREG32(reg) printk(KERN_INFO "REGISTER: " #reg " : 0x%08X\n", amdgpu_device_rreg(adev, (reg), 0))
#define WREG32(reg, v) amdgpu_device_wreg(adev, (reg), (v), 0)
#define RREG32(reg) amdgpu_mm_rreg(adev, (reg), 0)
#define DREG32(reg) printk(KERN_INFO "REGISTER: " #reg " : 0x%08X\n", amdgpu_mm_rreg(adev, (reg), 0))
#define WREG32(reg, v) amdgpu_mm_wreg(adev, (reg), (v), 0)
#define REG_SET(FIELD, v) (((v) << FIELD##_SHIFT) & FIELD##_MASK)
#define REG_GET(FIELD, v) (((v) << FIELD##_SHIFT) & FIELD##_MASK)
#define RREG32_PCIE(reg) adev->pcie_rreg(adev, (reg))
@@ -1080,7 +1081,16 @@ int emu_soc_asic_init(struct amdgpu_device *adev);
		tmp_ |= ((val) & ~(mask));			\
		WREG32_PLL(reg, tmp_);				\
	} while (0)
#define DREG32_SYS(sqf, adev, reg) seq_printf((sqf), #reg " : 0x%08X\n", amdgpu_device_rreg((adev), (reg), false))

#define WREG32_SMC_P(_Reg, _Val, _Mask)                         \
	do {                                                    \
		u32 tmp = RREG32_SMC(_Reg);                     \
		tmp &= (_Mask);                                 \
		tmp |= ((_Val) & ~(_Mask));                     \
		WREG32_SMC(_Reg, tmp);                          \
	} while (0)

#define DREG32_SYS(sqf, adev, reg) seq_printf((sqf), #reg " : 0x%08X\n", amdgpu_mm_rreg((adev), (reg), false))
#define RREG32_IO(reg) amdgpu_io_rreg(adev, (reg))
#define WREG32_IO(reg, v) amdgpu_io_wreg(adev, (reg), (v))

+5 −7
Original line number Diff line number Diff line
@@ -31,8 +31,6 @@
#include "amdgpu_xgmi.h"
#include <uapi/linux/kfd_ioctl.h>

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
 */
@@ -113,7 +111,9 @@ void amdgpu_amdkfd_device_init(struct amdgpu_device *adev)

	if (adev->kfd.dev) {
		struct kgd2kfd_shared_resources gpu_resources = {
			.compute_vmid_bitmap = compute_vmid_bitmap,
			.compute_vmid_bitmap =
				((1 << AMDGPU_NUM_VMID) - 1) -
				((1 << adev->vm_manager.first_kfd_vmid) - 1),
			.num_pipe_per_mec = adev->gfx.mec.num_pipe_per_mec,
			.num_queue_per_pipe = adev->gfx.mec.num_queue_per_pipe,
			.gpuvm_size = min(adev->vm_manager.max_pfn
@@ -637,10 +637,8 @@ 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.dev) {
		if ((1 << vmid) & compute_vmid_bitmap)
			return true;
	}
	if (adev->kfd.dev)
		return vmid >= adev->vm_manager.first_kfd_vmid;

	return false;
}
+10 −0
Original line number Diff line number Diff line
@@ -111,6 +111,7 @@ int amdgpu_atomfirmware_allocate_fb_scratch(struct amdgpu_device *adev)

union igp_info {
	struct atom_integrated_system_info_v1_11 v11;
	struct atom_integrated_system_info_v1_12 v12;
};

union umc_info {
@@ -214,6 +215,15 @@ amdgpu_atomfirmware_get_vram_info(struct amdgpu_device *adev,
				if (vram_type)
					*vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type);
				break;
			case 12:
				mem_channel_number = igp_info->v12.umachannelnumber;
				/* channel width is 64 */
				if (vram_width)
					*vram_width = mem_channel_number * 64;
				mem_type = igp_info->v12.memorytype;
				if (vram_type)
					*vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type);
				break;
			default:
				return -EINVAL;
			}
+19 −7
Original line number Diff line number Diff line
@@ -1343,27 +1343,37 @@ static void amdgpu_ib_preempt_job_recovery(struct drm_gpu_scheduler *sched)
static void amdgpu_ib_preempt_mark_partial_job(struct amdgpu_ring *ring)
{
	struct amdgpu_job *job;
	struct drm_sched_job *s_job;
	struct drm_sched_job *s_job, *tmp;
	uint32_t preempt_seq;
	struct dma_fence *fence, **ptr;
	struct amdgpu_fence_driver *drv = &ring->fence_drv;
	struct drm_gpu_scheduler *sched = &ring->sched;
	bool preempted = true;

	if (ring->funcs->type != AMDGPU_RING_TYPE_GFX)
		return;

	preempt_seq = le32_to_cpu(*(drv->cpu_addr + 2));
	if (preempt_seq <= atomic_read(&drv->last_seq))
		return;
	if (preempt_seq <= atomic_read(&drv->last_seq)) {
		preempted = false;
		goto no_preempt;
	}

	preempt_seq &= drv->num_fences_mask;
	ptr = &drv->fences[preempt_seq];
	fence = rcu_dereference_protected(*ptr, 1);

no_preempt:
	spin_lock(&sched->job_list_lock);
	list_for_each_entry(s_job, &sched->ring_mirror_list, node) {
	list_for_each_entry_safe(s_job, tmp, &sched->ring_mirror_list, node) {
		if (dma_fence_is_signaled(&s_job->s_fence->finished)) {
			/* remove job from ring_mirror_list */
			list_del_init(&s_job->node);
			sched->ops->free_job(s_job);
			continue;
		}
		job = to_amdgpu_job(s_job);
		if (job->fence == fence)
		if (preempted && job->fence == fence)
			/* mark the job as preempted */
			job->preemption_status |= AMDGPU_IB_PREEMPTED;
	}
@@ -1461,10 +1471,12 @@ static int amdgpu_debugfs_sclk_set(void *data, u64 val)
	}

	if (is_support_sw_smu(adev)) {
		ret = smu_get_dpm_freq_range(&adev->smu, SMU_SCLK, &min_freq, &max_freq, true);
		ret = smu_get_dpm_freq_range(&adev->smu, SMU_SCLK, &min_freq, &max_freq);
		if (ret || val > max_freq || val < min_freq)
			return -EINVAL;
		ret = smu_set_soft_freq_range(&adev->smu, SMU_SCLK, (uint32_t)val, (uint32_t)val, true);
		ret = smu_set_soft_freq_range(&adev->smu, SMU_SCLK, (uint32_t)val, (uint32_t)val);
	} else {
		return 0;
	}

	pm_runtime_mark_last_busy(adev->ddev->dev);
+70 −73
Original line number Diff line number Diff line
@@ -81,6 +81,7 @@ MODULE_FIRMWARE("amdgpu/navi10_gpu_info.bin");
MODULE_FIRMWARE("amdgpu/navi14_gpu_info.bin");
MODULE_FIRMWARE("amdgpu/navi12_gpu_info.bin");
MODULE_FIRMWARE("amdgpu/sienna_cichlid_gpu_info.bin");
MODULE_FIRMWARE("amdgpu/navy_flounder_gpu_info.bin");

#define AMDGPU_RESUME_MS		2000

@@ -114,6 +115,7 @@ const char *amdgpu_asic_name[] = {
	"NAVI14",
	"NAVI12",
	"SIENNA_CICHLID",
	"NAVY_FLOUNDER",
	"LAST",
};

@@ -301,10 +303,10 @@ void amdgpu_device_vram_access(struct amdgpu_device *adev, loff_t pos,
}

/*
 * device register access helper functions.
 * MMIO register access helper functions.
 */
/**
 * amdgpu_device_rreg - read a register
 * amdgpu_mm_rreg - read a memory mapped IO register
 *
 * @adev: amdgpu_device pointer
 * @reg: dword aligned register offset
@@ -312,7 +314,7 @@ void amdgpu_device_vram_access(struct amdgpu_device *adev, loff_t pos,
 *
 * Returns the 32 bit value from the offset specified.
 */
uint32_t amdgpu_device_rreg(struct amdgpu_device *adev, uint32_t reg,
uint32_t amdgpu_mm_rreg(struct amdgpu_device *adev, uint32_t reg,
			uint32_t acc_flags)
{
	uint32_t ret;
@@ -322,9 +324,15 @@ uint32_t amdgpu_device_rreg(struct amdgpu_device *adev, uint32_t reg,

	if ((reg * 4) < adev->rmmio_size)
		ret = readl(((void __iomem *)adev->rmmio) + (reg * 4));
	else
		ret = adev->pcie_rreg(adev, (reg * 4));
	trace_amdgpu_device_rreg(adev->pdev->device, reg, ret);
	else {
		unsigned long flags;

		spin_lock_irqsave(&adev->mmio_idx_lock, flags);
		writel((reg * 4), ((void __iomem *)adev->rmmio) + (mmMM_INDEX * 4));
		ret = readl(((void __iomem *)adev->rmmio) + (mmMM_DATA * 4));
		spin_unlock_irqrestore(&adev->mmio_idx_lock, flags);
	}
	trace_amdgpu_mm_rreg(adev->pdev->device, reg, ret);
	return ret;
}

@@ -370,19 +378,24 @@ void amdgpu_mm_wreg8(struct amdgpu_device *adev, uint32_t offset, uint8_t value)
		BUG();
}

void static inline amdgpu_device_wreg_no_kiq(struct amdgpu_device *adev, uint32_t reg,
					     uint32_t v, uint32_t acc_flags)
void static inline amdgpu_mm_wreg_mmio(struct amdgpu_device *adev, uint32_t reg, uint32_t v, uint32_t acc_flags)
{
	trace_amdgpu_device_wreg(adev->pdev->device, reg, v);
	trace_amdgpu_mm_wreg(adev->pdev->device, reg, v);

	if ((reg * 4) < adev->rmmio_size)
		writel(v, ((void __iomem *)adev->rmmio) + (reg * 4));
	else
		adev->pcie_wreg(adev, (reg * 4), v);
	else {
		unsigned long flags;

		spin_lock_irqsave(&adev->mmio_idx_lock, flags);
		writel((reg * 4), ((void __iomem *)adev->rmmio) + (mmMM_INDEX * 4));
		writel(v, ((void __iomem *)adev->rmmio) + (mmMM_DATA * 4));
		spin_unlock_irqrestore(&adev->mmio_idx_lock, flags);
	}
}

/**
 * amdgpu_device_wreg - write to a register
 * amdgpu_mm_wreg - write to a memory mapped IO register
 *
 * @adev: amdgpu_device pointer
 * @reg: dword aligned register offset
@@ -391,13 +404,13 @@ void static inline amdgpu_device_wreg_no_kiq(struct amdgpu_device *adev, uint32_
 *
 * Writes the value specified to the offset specified.
 */
void amdgpu_device_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v,
void amdgpu_mm_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v,
		    uint32_t acc_flags)
{
	if (!(acc_flags & AMDGPU_REGS_NO_KIQ) && amdgpu_sriov_runtime(adev))
		return amdgpu_kiq_wreg(adev, reg, v);

	amdgpu_device_wreg_no_kiq(adev, reg, v, acc_flags);
	amdgpu_mm_wreg_mmio(adev, reg, v, acc_flags);
}

/*
@@ -416,7 +429,7 @@ void amdgpu_mm_wreg_mmio_rlc(struct amdgpu_device *adev, uint32_t reg, uint32_t
			return adev->gfx.rlc.funcs->rlcg_wreg(adev, reg, v);
	}

	amdgpu_device_wreg_no_kiq(adev, reg, v, acc_flags);
	amdgpu_mm_wreg_mmio(adev, reg, v, acc_flags);
}

/**
@@ -1621,6 +1634,9 @@ static int amdgpu_device_parse_gpu_info_fw(struct amdgpu_device *adev)
	case CHIP_SIENNA_CICHLID:
		chip_name = "sienna_cichlid";
		break;
	case CHIP_NAVY_FLOUNDER:
		chip_name = "navy_flounder";
		break;
	}

	snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_gpu_info.bin", chip_name);
@@ -1722,6 +1738,12 @@ static int amdgpu_device_ip_early_init(struct amdgpu_device *adev)

	amdgpu_device_enable_virtual_display(adev);

	if (amdgpu_sriov_vf(adev)) {
		r = amdgpu_virt_request_full_gpu(adev, true);
		if (r)
			return r;
	}

	switch (adev->asic_type) {
#ifdef CONFIG_DRM_AMDGPU_SI
	case CHIP_VERDE:
@@ -1788,6 +1810,7 @@ static int amdgpu_device_ip_early_init(struct amdgpu_device *adev)
	case  CHIP_NAVI14:
	case  CHIP_NAVI12:
	case  CHIP_SIENNA_CICHLID:
	case  CHIP_NAVY_FLOUNDER:
		adev->family = AMDGPU_FAMILY_NV;

		r = nv_set_ip_blocks(adev);
@@ -1801,31 +1824,6 @@ static int amdgpu_device_ip_early_init(struct amdgpu_device *adev)

	amdgpu_amdkfd_device_probe(adev);

	if (amdgpu_sriov_vf(adev)) {
		/* handle vbios stuff prior full access mode for new handshake */
		if (adev->virt.req_init_data_ver == 1) {
			if (!amdgpu_get_bios(adev)) {
				DRM_ERROR("failed to get vbios\n");
				return -EINVAL;
			}

			r = amdgpu_atombios_init(adev);
			if (r) {
				dev_err(adev->dev, "amdgpu_atombios_init failed\n");
				amdgpu_vf_error_put(adev, AMDGIM_ERROR_VF_ATOMBIOS_INIT_FAIL, 0, 0);
				return r;
			}
		}
	}

	/* we need to send REQ_GPU here for legacy handshaker otherwise the vbios
	 * will not be prepared by host for this VF */
	if (amdgpu_sriov_vf(adev) && adev->virt.req_init_data_ver < 1) {
		r = amdgpu_virt_request_full_gpu(adev, true);
		if (r)
			return r;
	}

	adev->pm.pp_feature = amdgpu_pp_feature_mask;
	if (amdgpu_sriov_vf(adev) || sched_policy == KFD_SCHED_POLICY_NO_HWS)
		adev->pm.pp_feature &= ~PP_GFXOFF_MASK;
@@ -1857,10 +1855,6 @@ static int amdgpu_device_ip_early_init(struct amdgpu_device *adev)
			if (r)
				return r;

			/* skip vbios handling for new handshake */
			if (amdgpu_sriov_vf(adev) && adev->virt.req_init_data_ver == 1)
				continue;

			/* Read BIOS */
			if (!amdgpu_get_bios(adev))
				return -EINVAL;
@@ -1987,12 +1981,6 @@ static int amdgpu_device_ip_init(struct amdgpu_device *adev)
	if (r)
		return r;

	if (amdgpu_sriov_vf(adev) && adev->virt.req_init_data_ver > 0) {
		r = amdgpu_virt_request_full_gpu(adev, true);
		if (r)
			return -EAGAIN;
	}

	for (i = 0; i < adev->num_ip_blocks; i++) {
		if (!adev->ip_blocks[i].status.valid)
			continue;
@@ -2474,8 +2462,11 @@ static int amdgpu_device_ip_suspend_phase1(struct amdgpu_device *adev)
	for (i = adev->num_ip_blocks - 1; i >= 0; i--) {
		if (!adev->ip_blocks[i].status.valid)
			continue;

		/* displays are handled separately */
		if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_DCE) {
		if (adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_DCE)
			continue;

		/* XXX handle errors */
		r = adev->ip_blocks[i].version->funcs->suspend(adev);
		/* XXX handle errors */
@@ -2484,9 +2475,9 @@ static int amdgpu_device_ip_suspend_phase1(struct amdgpu_device *adev)
				  adev->ip_blocks[i].version->funcs->name, r);
			return r;
		}

		adev->ip_blocks[i].status.hw = false;
	}
	}

	return 0;
}
@@ -2817,6 +2808,7 @@ bool amdgpu_device_asic_has_dc_support(enum amd_asic_type asic_type)
#endif
#if defined(CONFIG_DRM_AMD_DC_DCN3_0)
	case CHIP_SIENNA_CICHLID:
	case CHIP_NAVY_FLOUNDER:
#endif
		return amdgpu_dc != 0;
#endif
@@ -3324,6 +3316,9 @@ fence_driver_init:
	queue_delayed_work(system_wq, &adev->delayed_init_work,
			   msecs_to_jiffies(AMDGPU_RESUME_MS));

	if (amdgpu_sriov_vf(adev))
		flush_delayed_work(&adev->delayed_init_work);

	r = sysfs_create_files(&adev->dev->kobj, amdgpu_dev_attributes);
	if (r) {
		dev_err(adev->dev, "Could not create amdgpu device attr\n");
@@ -3951,6 +3946,7 @@ bool amdgpu_device_should_recover_gpu(struct amdgpu_device *adev)
		case CHIP_NAVI10:
		case CHIP_NAVI14:
		case CHIP_NAVI12:
		case CHIP_SIENNA_CICHLID:
			break;
		default:
			goto disabled;
@@ -4256,18 +4252,19 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
	struct amdgpu_hive_info *hive = NULL;
	struct amdgpu_device *tmp_adev = NULL;
	int i, r = 0;
	bool in_ras_intr = amdgpu_ras_intr_triggered();
	bool use_baco =
		(amdgpu_asic_reset_method(adev) == AMD_RESET_METHOD_BACO) ?
		true : false;
	bool need_emergency_restart = false;
	bool audio_suspended = false;

	/**
	 * Special case: RAS triggered and full reset isn't supported
	 */
	need_emergency_restart = amdgpu_ras_need_emergency_restart(adev);

	/*
	 * Flush RAM to disk so that after reboot
	 * the user can read log and see why the system rebooted.
	 */
	if (in_ras_intr && !use_baco && amdgpu_ras_get_context(adev)->reboot) {

	if (need_emergency_restart && amdgpu_ras_get_context(adev)->reboot) {
		DRM_WARN("Emergency reboot.");

		ksys_sync_helper();
@@ -4275,7 +4272,7 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
	}

	dev_info(adev->dev, "GPU %s begin!\n",
		(in_ras_intr && !use_baco) ? "jobs stop":"reset");
		need_emergency_restart ? "jobs stop":"reset");

	/*
	 * Here we trylock to avoid chain of resets executing from
@@ -4347,7 +4344,7 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
		amdgpu_fbdev_set_suspend(tmp_adev, 1);

		/* disable ras on ALL IPs */
		if (!(in_ras_intr && !use_baco) &&
		if (!need_emergency_restart &&
		      amdgpu_device_ip_need_full_reset(tmp_adev))
			amdgpu_ras_suspend(tmp_adev);

@@ -4359,12 +4356,12 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,

			drm_sched_stop(&ring->sched, job ? &job->base : NULL);

			if (in_ras_intr && !use_baco)
			if (need_emergency_restart)
				amdgpu_job_stop_all_jobs_on_sched(&ring->sched);
		}
	}

	if (in_ras_intr && !use_baco)
	if (need_emergency_restart)
		goto skip_sched_resume;

	/*
@@ -4441,7 +4438,7 @@ skip_hw_reset:
skip_sched_resume:
	list_for_each_entry(tmp_adev, device_list_handle, gmc.xgmi.head) {
		/*unlock kfd: SRIOV would do it separately */
		if (!(in_ras_intr && !use_baco) && !amdgpu_sriov_vf(tmp_adev))
		if (!need_emergency_restart && !amdgpu_sriov_vf(tmp_adev))
	                amdgpu_amdkfd_post_reset(tmp_adev);
		if (audio_suspended)
			amdgpu_device_resume_display_audio(tmp_adev);
Loading