diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu')
22 files changed, 167 insertions, 92 deletions
| diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index c4a21c6428f5..1bcbade479dc 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -1591,6 +1591,8 @@ struct amdgpu_uvd {  	struct amdgpu_bo	*vcpu_bo;  	void			*cpu_addr;  	uint64_t		gpu_addr; +	unsigned		fw_version; +	void			*saved_bo;  	atomic_t		handles[AMDGPU_MAX_UVD_HANDLES];  	struct drm_file		*filp[AMDGPU_MAX_UVD_HANDLES];  	struct delayed_work	idle_work; @@ -2033,6 +2035,7 @@ struct amdgpu_device {  	/* tracking pinned memory */  	u64 vram_pin_size; +	u64 invisible_pin_size;  	u64 gart_pin_size;  	/* amdkfd interface */ diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c index d6b0bff510aa..b7b583c42ea8 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c @@ -425,6 +425,10 @@ static int acp_resume(void *handle)  	struct acp_pm_domain *apd;  	struct amdgpu_device *adev = (struct amdgpu_device *)handle; +	/* return early if no ACP */ +	if (!adev->acp.acp_genpd) +		return 0; +  	/* SMU block will power on ACP irrespective of ACP runtime status.  	 * Power off explicitly based on genpd ACP runtime status so that ACP  	 * hw and ACP-genpd status are in sync. diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c index 0020a0ea43ff..35a1248aaa77 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c @@ -63,10 +63,6 @@ bool amdgpu_has_atpx(void) {  	return amdgpu_atpx_priv.atpx_detected;  } -bool amdgpu_has_atpx_dgpu_power_cntl(void) { -	return amdgpu_atpx_priv.atpx.functions.power_cntl; -} -  /**   * amdgpu_atpx_call - call an ATPX method   * @@ -146,6 +142,13 @@ static void amdgpu_atpx_parse_functions(struct amdgpu_atpx_functions *f, u32 mas   */  static int amdgpu_atpx_validate(struct amdgpu_atpx *atpx)  { +	/* make sure required functions are enabled */ +	/* dGPU power control is required */ +	if (atpx->functions.power_cntl == false) { +		printk("ATPX dGPU power cntl not present, forcing\n"); +		atpx->functions.power_cntl = true; +	} +  	if (atpx->functions.px_params) {  		union acpi_object *info;  		struct atpx_px_params output; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c index 7a4b101e10c6..6043dc7c3a94 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c @@ -816,10 +816,13 @@ static int amdgpu_cgs_get_active_displays_info(void *cgs_device,  	struct drm_device *ddev = adev->ddev;  	struct drm_crtc *crtc;  	uint32_t line_time_us, vblank_lines; +	struct cgs_mode_info *mode_info;  	if (info == NULL)  		return -EINVAL; +	mode_info = info->mode_info; +  	if (adev->mode_info.num_crtc && adev->mode_info.mode_config_initialized) {  		list_for_each_entry(crtc,  				&ddev->mode_config.crtc_list, head) { @@ -828,7 +831,7 @@ static int amdgpu_cgs_get_active_displays_info(void *cgs_device,  				info->active_display_mask |= (1 << amdgpu_crtc->crtc_id);  				info->display_count++;  			} -			if (info->mode_info != NULL && +			if (mode_info != NULL &&  				crtc->enabled && amdgpu_crtc->enabled &&  				amdgpu_crtc->hw_mode.clock) {  				line_time_us = (amdgpu_crtc->hw_mode.crtc_htotal * 1000) / @@ -836,10 +839,10 @@ static int amdgpu_cgs_get_active_displays_info(void *cgs_device,  				vblank_lines = amdgpu_crtc->hw_mode.crtc_vblank_end -  							amdgpu_crtc->hw_mode.crtc_vdisplay +  							(amdgpu_crtc->v_border * 2); -				info->mode_info->vblank_time_us = vblank_lines * line_time_us; -				info->mode_info->refresh_rate = drm_mode_vrefresh(&amdgpu_crtc->hw_mode); -				info->mode_info->ref_clock = adev->clock.spll.reference_freq; -				info->mode_info++; +				mode_info->vblank_time_us = vblank_lines * line_time_us; +				mode_info->refresh_rate = drm_mode_vrefresh(&amdgpu_crtc->hw_mode); +				mode_info->ref_clock = adev->clock.spll.reference_freq; +				mode_info = NULL;  			}  		}  	} @@ -847,6 +850,16 @@ static int amdgpu_cgs_get_active_displays_info(void *cgs_device,  	return 0;  } + +static int amdgpu_cgs_notify_dpm_enabled(void *cgs_device, bool enabled) +{ +	CGS_FUNC_ADEV; + +	adev->pm.dpm_enabled = enabled; + +	return 0; +} +  /** \brief evaluate acpi namespace object, handle or pathname must be valid   *  \param cgs_device   *  \param info input/output arguments for the control method @@ -1097,6 +1110,7 @@ static const struct cgs_ops amdgpu_cgs_ops = {  	amdgpu_cgs_set_powergating_state,  	amdgpu_cgs_set_clockgating_state,  	amdgpu_cgs_get_active_displays_info, +	amdgpu_cgs_notify_dpm_enabled,  	amdgpu_cgs_call_acpi_method,  	amdgpu_cgs_query_system_info,  }; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 612117478b57..2139da773da6 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -62,12 +62,6 @@ static const char *amdgpu_asic_name[] = {  	"LAST",  }; -#if defined(CONFIG_VGA_SWITCHEROO) -bool amdgpu_has_atpx_dgpu_power_cntl(void); -#else -static inline bool amdgpu_has_atpx_dgpu_power_cntl(void) { return false; } -#endif -  bool amdgpu_device_is_px(struct drm_device *dev)  {  	struct amdgpu_device *adev = dev->dev_private; @@ -1485,7 +1479,7 @@ int amdgpu_device_init(struct amdgpu_device *adev,  	if (amdgpu_runtime_pm == 1)  		runtime = true; -	if (amdgpu_device_is_px(ddev) && amdgpu_has_atpx_dgpu_power_cntl()) +	if (amdgpu_device_is_px(ddev))  		runtime = true;  	vga_switcheroo_register_client(adev->pdev, &amdgpu_switcheroo_ops, runtime);  	if (runtime) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c index f0ed974bd4e0..3fb405b3a614 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c @@ -57,7 +57,7 @@ static bool amdgpu_flip_handle_fence(struct amdgpu_flip_work *work,  	if (!fence_add_callback(fence, &work->cb, amdgpu_flip_callback))  		return true; -	fence_put(*f); +	fence_put(fence);  	return false;  } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c index 4303b447efe8..d81f1f4883a6 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c @@ -121,7 +121,7 @@ int amdgpu_fence_emit(struct amdgpu_ring *ring, struct fence **f)  {  	struct amdgpu_device *adev = ring->adev;  	struct amdgpu_fence *fence; -	struct fence **ptr; +	struct fence *old, **ptr;  	uint32_t seq;  	fence = kmem_cache_alloc(amdgpu_fence_slab, GFP_KERNEL); @@ -141,7 +141,11 @@ int amdgpu_fence_emit(struct amdgpu_ring *ring, struct fence **f)  	/* This function can't be called concurrently anyway, otherwise  	 * emitting the fence would mess up the hardware ring buffer.  	 */ -	BUG_ON(rcu_dereference_protected(*ptr, 1)); +	old = rcu_dereference_protected(*ptr, 1); +	if (old && !fence_is_signaled(old)) { +		DRM_INFO("rcu slot is busy\n"); +		fence_wait(old, false); +	}  	rcu_assign_pointer(*ptr, fence_get(&fence->base)); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c index f594cfaa97e5..762cfdb85147 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c @@ -219,6 +219,8 @@ int amdgpu_irq_init(struct amdgpu_device *adev)  	if (r) {  		return r;  	} +	adev->ddev->vblank_disable_allowed = true; +  	/* enable msi */  	adev->irq.msi_enabled = false; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index 7805a8706af7..b04337de65d1 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c @@ -303,7 +303,7 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file  			fw_info.feature = adev->vce.fb_version;  			break;  		case AMDGPU_INFO_FW_UVD: -			fw_info.ver = 0; +			fw_info.ver = adev->uvd.fw_version;  			fw_info.feature = 0;  			break;  		case AMDGPU_INFO_FW_GMC: @@ -382,8 +382,9 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file  		struct drm_amdgpu_info_vram_gtt vram_gtt;  		vram_gtt.vram_size = adev->mc.real_vram_size; +		vram_gtt.vram_size -= adev->vram_pin_size;  		vram_gtt.vram_cpu_accessible_size = adev->mc.visible_vram_size; -		vram_gtt.vram_cpu_accessible_size -= adev->vram_pin_size; +		vram_gtt.vram_cpu_accessible_size -= (adev->vram_pin_size - adev->invisible_pin_size);  		vram_gtt.gtt_size  = adev->mc.gtt_size;  		vram_gtt.gtt_size -= adev->gart_pin_size;  		return copy_to_user(out, &vram_gtt, diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h index 8d432e6901af..81bd964d3dfc 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h @@ -53,7 +53,7 @@ struct amdgpu_hpd;  #define AMDGPU_MAX_HPD_PINS 6  #define AMDGPU_MAX_CRTCS 6 -#define AMDGPU_MAX_AFMT_BLOCKS 7 +#define AMDGPU_MAX_AFMT_BLOCKS 9  enum amdgpu_rmx_type {  	RMX_OFF, @@ -309,8 +309,8 @@ struct amdgpu_mode_info {  	struct atom_context *atom_context;  	struct card_info *atom_card_info;  	bool mode_config_initialized; -	struct amdgpu_crtc *crtcs[6]; -	struct amdgpu_afmt *afmt[7]; +	struct amdgpu_crtc *crtcs[AMDGPU_MAX_CRTCS]; +	struct amdgpu_afmt *afmt[AMDGPU_MAX_AFMT_BLOCKS];  	/* DVI-I properties */  	struct drm_property *coherent_mode_property;  	/* DAC enable load detect */ diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c index 151a2d42c639..7ecea83ce453 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c @@ -424,9 +424,11 @@ int amdgpu_bo_pin_restricted(struct amdgpu_bo *bo, u32 domain,  		bo->pin_count = 1;  		if (gpu_addr != NULL)  			*gpu_addr = amdgpu_bo_gpu_offset(bo); -		if (domain == AMDGPU_GEM_DOMAIN_VRAM) +		if (domain == AMDGPU_GEM_DOMAIN_VRAM) {  			bo->adev->vram_pin_size += amdgpu_bo_size(bo); -		else +			if (bo->flags & AMDGPU_GEM_CREATE_NO_CPU_ACCESS) +				bo->adev->invisible_pin_size += amdgpu_bo_size(bo); +		} else  			bo->adev->gart_pin_size += amdgpu_bo_size(bo);  	} else {  		dev_err(bo->adev->dev, "%p pin failed\n", bo); @@ -456,9 +458,11 @@ int amdgpu_bo_unpin(struct amdgpu_bo *bo)  	}  	r = ttm_bo_validate(&bo->tbo, &bo->placement, false, false);  	if (likely(r == 0)) { -		if (bo->tbo.mem.mem_type == TTM_PL_VRAM) +		if (bo->tbo.mem.mem_type == TTM_PL_VRAM) {  			bo->adev->vram_pin_size -= amdgpu_bo_size(bo); -		else +			if (bo->flags & AMDGPU_GEM_CREATE_NO_CPU_ACCESS) +				bo->adev->invisible_pin_size -= amdgpu_bo_size(bo); +		} else  			bo->adev->gart_pin_size -= amdgpu_bo_size(bo);  	} else {  		dev_err(bo->adev->dev, "%p validate failed for unpin\n", bo); @@ -476,6 +480,17 @@ int amdgpu_bo_evict_vram(struct amdgpu_device *adev)  	return ttm_bo_evict_mm(&adev->mman.bdev, TTM_PL_VRAM);  } +static const char *amdgpu_vram_names[] = { +	"UNKNOWN", +	"GDDR1", +	"DDR2", +	"GDDR3", +	"GDDR4", +	"GDDR5", +	"HBM", +	"DDR3" +}; +  int amdgpu_bo_init(struct amdgpu_device *adev)  {  	/* Add an MTRR for the VRAM */ @@ -484,8 +499,8 @@ int amdgpu_bo_init(struct amdgpu_device *adev)  	DRM_INFO("Detected VRAM RAM=%lluM, BAR=%lluM\n",  		adev->mc.mc_vram_size >> 20,  		(unsigned long long)adev->mc.aper_size >> 20); -	DRM_INFO("RAM width %dbits DDR\n", -			adev->mc.vram_width); +	DRM_INFO("RAM width %dbits %s\n", +		 adev->mc.vram_width, amdgpu_vram_names[adev->mc.vram_type]);  	return amdgpu_ttm_init(adev);  } @@ -526,6 +541,7 @@ int amdgpu_bo_set_metadata (struct amdgpu_bo *bo, void *metadata,  	if (!metadata_size) {  		if (bo->metadata_size) {  			kfree(bo->metadata); +			bo->metadata = NULL;  			bo->metadata_size = 0;  		}  		return 0; @@ -608,6 +624,10 @@ int amdgpu_bo_fault_reserve_notify(struct ttm_buffer_object *bo)  	if ((offset + size) <= adev->mc.visible_vram_size)  		return 0; +	/* Can't move a pinned BO to visible VRAM */ +	if (abo->pin_count > 0) +		return -EINVAL; +  	/* hurrah the memory is not visible ! */  	amdgpu_ttm_placement_from_domain(abo, AMDGPU_GEM_DOMAIN_VRAM);  	lpfn =	adev->mc.visible_vram_size >> PAGE_SHIFT; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c index 3cb6d6c413c7..e9c6ae6ed2f7 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c @@ -143,7 +143,7 @@ static int amdgpu_pp_late_init(void *handle)  					adev->powerplay.pp_handle);  #ifdef CONFIG_DRM_AMD_POWERPLAY -	if (adev->pp_enabled) { +	if (adev->pp_enabled && adev->pm.dpm_enabled) {  		amdgpu_pm_sysfs_init(adev);  		amdgpu_dpm_dispatch_task(adev, AMD_PP_EVENT_COMPLETE_INIT, NULL, NULL);  	} @@ -161,12 +161,8 @@ static int amdgpu_pp_sw_init(void *handle)  					adev->powerplay.pp_handle);  #ifdef CONFIG_DRM_AMD_POWERPLAY -	if (adev->pp_enabled) { -		if (amdgpu_dpm == 0) -			adev->pm.dpm_enabled = false; -		else -			adev->pm.dpm_enabled = true; -	} +	if (adev->pp_enabled) +		adev->pm.dpm_enabled = true;  #endif  	return ret; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index ab34190859a8..11af4492b4be 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c @@ -223,6 +223,8 @@ static int amdgpu_verify_access(struct ttm_buffer_object *bo, struct file *filp)  {  	struct amdgpu_bo *rbo = container_of(bo, struct amdgpu_bo, tbo); +	if (amdgpu_ttm_tt_get_usermm(bo->ttm)) +		return -EPERM;  	return drm_vma_node_verify_access(&rbo->gem_base.vma_node, filp);  } @@ -384,9 +386,15 @@ static int amdgpu_bo_move(struct ttm_buffer_object *bo,  			struct ttm_mem_reg *new_mem)  {  	struct amdgpu_device *adev; +	struct amdgpu_bo *abo;  	struct ttm_mem_reg *old_mem = &bo->mem;  	int r; +	/* Can't move a pinned BO */ +	abo = container_of(bo, struct amdgpu_bo, tbo); +	if (WARN_ON_ONCE(abo->pin_count > 0)) +		return -EINVAL; +  	adev = amdgpu_get_adev(bo->bdev);  	if (old_mem->mem_type == TTM_PL_SYSTEM && bo->ttm == NULL) {  		amdgpu_move_null(bo, new_mem); @@ -616,7 +624,7 @@ static void amdgpu_ttm_tt_unpin_userptr(struct ttm_tt *ttm)  			set_page_dirty(page);  		mark_page_accessed(page); -		page_cache_release(page); +		put_page(page);  	}  	sg_free_table(ttm->sg); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c index c1a581044417..871018c634e0 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c @@ -158,6 +158,9 @@ int amdgpu_uvd_sw_init(struct amdgpu_device *adev)  	DRM_INFO("Found UVD firmware Version: %hu.%hu Family ID: %hu\n",  		version_major, version_minor, family_id); +	adev->uvd.fw_version = ((version_major << 24) | (version_minor << 16) | +				(family_id << 8)); +  	bo_size = AMDGPU_GPU_PAGE_ALIGN(le32_to_cpu(hdr->ucode_size_bytes) + 8)  		 +  AMDGPU_UVD_STACK_SIZE + AMDGPU_UVD_HEAP_SIZE;  	r = amdgpu_bo_create(adev, bo_size, PAGE_SIZE, true, @@ -241,32 +244,30 @@ int amdgpu_uvd_sw_fini(struct amdgpu_device *adev)  int amdgpu_uvd_suspend(struct amdgpu_device *adev)  { -	struct amdgpu_ring *ring = &adev->uvd.ring; -	int i, r; +	unsigned size; +	void *ptr; +	int i;  	if (adev->uvd.vcpu_bo == NULL)  		return 0; -	for (i = 0; i < AMDGPU_MAX_UVD_HANDLES; ++i) { -		uint32_t handle = atomic_read(&adev->uvd.handles[i]); -		if (handle != 0) { -			struct fence *fence; +	for (i = 0; i < AMDGPU_MAX_UVD_HANDLES; ++i) +		if (atomic_read(&adev->uvd.handles[i])) +			break; -			amdgpu_uvd_note_usage(adev); +	if (i == AMDGPU_MAX_UVD_HANDLES) +		return 0; -			r = amdgpu_uvd_get_destroy_msg(ring, handle, false, &fence); -			if (r) { -				DRM_ERROR("Error destroying UVD (%d)!\n", r); -				continue; -			} +	cancel_delayed_work_sync(&adev->uvd.idle_work); -			fence_wait(fence, false); -			fence_put(fence); +	size = amdgpu_bo_size(adev->uvd.vcpu_bo); +	ptr = adev->uvd.cpu_addr; -			adev->uvd.filp[i] = NULL; -			atomic_set(&adev->uvd.handles[i], 0); -		} -	} +	adev->uvd.saved_bo = kmalloc(size, GFP_KERNEL); +	if (!adev->uvd.saved_bo) +		return -ENOMEM; + +	memcpy(adev->uvd.saved_bo, ptr, size);  	return 0;  } @@ -275,23 +276,29 @@ int amdgpu_uvd_resume(struct amdgpu_device *adev)  {  	unsigned size;  	void *ptr; -	const struct common_firmware_header *hdr; -	unsigned offset;  	if (adev->uvd.vcpu_bo == NULL)  		return -EINVAL; -	hdr = (const struct common_firmware_header *)adev->uvd.fw->data; -	offset = le32_to_cpu(hdr->ucode_array_offset_bytes); -	memcpy(adev->uvd.cpu_addr, (adev->uvd.fw->data) + offset, -		(adev->uvd.fw->size) - offset); -  	size = amdgpu_bo_size(adev->uvd.vcpu_bo); -	size -= le32_to_cpu(hdr->ucode_size_bytes);  	ptr = adev->uvd.cpu_addr; -	ptr += le32_to_cpu(hdr->ucode_size_bytes); -	memset(ptr, 0, size); +	if (adev->uvd.saved_bo != NULL) { +		memcpy(ptr, adev->uvd.saved_bo, size); +		kfree(adev->uvd.saved_bo); +		adev->uvd.saved_bo = NULL; +	} else { +		const struct common_firmware_header *hdr; +		unsigned offset; + +		hdr = (const struct common_firmware_header *)adev->uvd.fw->data; +		offset = le32_to_cpu(hdr->ucode_array_offset_bytes); +		memcpy(adev->uvd.cpu_addr, (adev->uvd.fw->data) + offset, +			(adev->uvd.fw->size) - offset); +		size -= le32_to_cpu(hdr->ucode_size_bytes); +		ptr += le32_to_cpu(hdr->ucode_size_bytes); +		memset(ptr, 0, size); +	}  	return 0;  } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c index 4bec0c108cea..481a64fa9b47 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c @@ -234,6 +234,7 @@ int amdgpu_vce_suspend(struct amdgpu_device *adev)  	if (i == AMDGPU_MAX_VCE_HANDLES)  		return 0; +	cancel_delayed_work_sync(&adev->vce.idle_work);  	/* TODO: suspending running encoding sessions isn't supported */  	return -EINVAL;  } diff --git a/drivers/gpu/drm/amd/amdgpu/atombios_encoders.c b/drivers/gpu/drm/amd/amdgpu/atombios_encoders.c index 1e0bba29e167..1cd6de575305 100644 --- a/drivers/gpu/drm/amd/amdgpu/atombios_encoders.c +++ b/drivers/gpu/drm/amd/amdgpu/atombios_encoders.c @@ -298,6 +298,10 @@ bool amdgpu_atombios_encoder_mode_fixup(struct drm_encoder *encoder,  	    && (mode->crtc_vsync_start < (mode->crtc_vdisplay + 2)))  		adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + 2; +	/* vertical FP must be at least 1 */ +	if (mode->crtc_vsync_start == mode->crtc_vdisplay) +		adjusted_mode->crtc_vsync_start++; +  	/* get the native mode for scaling */  	if (amdgpu_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT))  		amdgpu_panel_mode_fixup(encoder, adjusted_mode); diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c index 82ce7d943884..a4a2e6cc61bb 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c @@ -903,14 +903,6 @@ static int gmc_v7_0_early_init(void *handle)  	gmc_v7_0_set_gart_funcs(adev);  	gmc_v7_0_set_irq_funcs(adev); -	if (adev->flags & AMD_IS_APU) { -		adev->mc.vram_type = AMDGPU_VRAM_TYPE_UNKNOWN; -	} else { -		u32 tmp = RREG32(mmMC_SEQ_MISC0); -		tmp &= MC_SEQ_MISC0__MT__MASK; -		adev->mc.vram_type = gmc_v7_0_convert_vram_type(tmp); -	} -  	return 0;  } @@ -918,7 +910,10 @@ static int gmc_v7_0_late_init(void *handle)  {  	struct amdgpu_device *adev = (struct amdgpu_device *)handle; -	return amdgpu_irq_get(adev, &adev->mc.vm_fault, 0); +	if (amdgpu_vm_fault_stop != AMDGPU_VM_FAULT_STOP_ALWAYS) +		return amdgpu_irq_get(adev, &adev->mc.vm_fault, 0); +	else +		return 0;  }  static int gmc_v7_0_sw_init(void *handle) @@ -927,6 +922,14 @@ static int gmc_v7_0_sw_init(void *handle)  	int dma_bits;  	struct amdgpu_device *adev = (struct amdgpu_device *)handle; +	if (adev->flags & AMD_IS_APU) { +		adev->mc.vram_type = AMDGPU_VRAM_TYPE_UNKNOWN; +	} else { +		u32 tmp = RREG32(mmMC_SEQ_MISC0); +		tmp &= MC_SEQ_MISC0__MT__MASK; +		adev->mc.vram_type = gmc_v7_0_convert_vram_type(tmp); +	} +  	r = amdgpu_irq_add_id(adev, 146, &adev->mc.vm_fault);  	if (r)  		return r; diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c index 29bd7b57dc91..7a9db2c72c89 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c @@ -863,14 +863,6 @@ static int gmc_v8_0_early_init(void *handle)  	gmc_v8_0_set_gart_funcs(adev);  	gmc_v8_0_set_irq_funcs(adev); -	if (adev->flags & AMD_IS_APU) { -		adev->mc.vram_type = AMDGPU_VRAM_TYPE_UNKNOWN; -	} else { -		u32 tmp = RREG32(mmMC_SEQ_MISC0); -		tmp &= MC_SEQ_MISC0__MT__MASK; -		adev->mc.vram_type = gmc_v8_0_convert_vram_type(tmp); -	} -  	return 0;  } @@ -878,15 +870,33 @@ static int gmc_v8_0_late_init(void *handle)  {  	struct amdgpu_device *adev = (struct amdgpu_device *)handle; -	return amdgpu_irq_get(adev, &adev->mc.vm_fault, 0); +	if (amdgpu_vm_fault_stop != AMDGPU_VM_FAULT_STOP_ALWAYS) +		return amdgpu_irq_get(adev, &adev->mc.vm_fault, 0); +	else +		return 0;  } +#define mmMC_SEQ_MISC0_FIJI 0xA71 +  static int gmc_v8_0_sw_init(void *handle)  {  	int r;  	int dma_bits;  	struct amdgpu_device *adev = (struct amdgpu_device *)handle; +	if (adev->flags & AMD_IS_APU) { +		adev->mc.vram_type = AMDGPU_VRAM_TYPE_UNKNOWN; +	} else { +		u32 tmp; + +		if (adev->asic_type == CHIP_FIJI) +			tmp = RREG32(mmMC_SEQ_MISC0_FIJI); +		else +			tmp = RREG32(mmMC_SEQ_MISC0); +		tmp &= MC_SEQ_MISC0__MT__MASK; +		adev->mc.vram_type = gmc_v8_0_convert_vram_type(tmp); +	} +  	r = amdgpu_irq_add_id(adev, 146, &adev->mc.vm_fault);  	if (r)  		return r; diff --git a/drivers/gpu/drm/amd/amdgpu/tonga_ih.c b/drivers/gpu/drm/amd/amdgpu/tonga_ih.c index b6f7d7bff929..0f14199cf716 100644 --- a/drivers/gpu/drm/amd/amdgpu/tonga_ih.c +++ b/drivers/gpu/drm/amd/amdgpu/tonga_ih.c @@ -307,7 +307,7 @@ static int tonga_ih_sw_fini(void *handle)  	amdgpu_irq_fini(adev);  	amdgpu_ih_ring_fini(adev); -	amdgpu_irq_add_domain(adev); +	amdgpu_irq_remove_domain(adev);  	return 0;  } diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c b/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c index c606ccb38d8b..cb463753115b 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c @@ -224,11 +224,11 @@ static int uvd_v4_2_suspend(void *handle)  	int r;  	struct amdgpu_device *adev = (struct amdgpu_device *)handle; -	r = amdgpu_uvd_suspend(adev); +	r = uvd_v4_2_hw_fini(adev);  	if (r)  		return r; -	r = uvd_v4_2_hw_fini(adev); +	r = amdgpu_uvd_suspend(adev);  	if (r)  		return r; diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c index e3c852d9d79a..16476d80f475 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c @@ -220,11 +220,11 @@ static int uvd_v5_0_suspend(void *handle)  	int r;  	struct amdgpu_device *adev = (struct amdgpu_device *)handle; -	r = amdgpu_uvd_suspend(adev); +	r = uvd_v5_0_hw_fini(adev);  	if (r)  		return r; -	r = uvd_v5_0_hw_fini(adev); +	r = amdgpu_uvd_suspend(adev);  	if (r)  		return r; diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c index 3375e614ac67..d49379145ef2 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c @@ -214,15 +214,16 @@ static int uvd_v6_0_suspend(void *handle)  	int r;  	struct amdgpu_device *adev = (struct amdgpu_device *)handle; +	r = uvd_v6_0_hw_fini(adev); +	if (r) +		return r; +  	/* Skip this for APU for now */  	if (!(adev->flags & AMD_IS_APU)) {  		r = amdgpu_uvd_suspend(adev);  		if (r)  			return r;  	} -	r = uvd_v6_0_hw_fini(adev); -	if (r) -		return r;  	return r;  } | 
