diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu')
25 files changed, 150 insertions, 82 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 039b57e4644c..496f72b134eb 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -459,6 +459,7 @@ struct amdgpu_bo {  	u64				metadata_flags;  	void				*metadata;  	u32				metadata_size; +	unsigned			prime_shared_count;  	/* list of all virtual address to which this bo  	 * is associated to  	 */ diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c index 892d60fb225b..2057683f7b59 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c @@ -395,9 +395,12 @@ static int acp_hw_fini(void *handle)  {  	int i, ret;  	struct device *dev; -  	struct amdgpu_device *adev = (struct amdgpu_device *)handle; +	/* return early if no ACP */ +	if (!adev->acp.acp_genpd) +		return 0; +  	for (i = 0; i < ACP_DEVS ; i++) {  		dev = get_mfd_cell_dev(adev->acp.acp_cell[i].name, i);  		ret = pm_genpd_remove_device(&adev->acp.acp_genpd->gpd, dev); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c index dae35a96a694..02ca5dd978f6 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c @@ -34,6 +34,7 @@ struct amdgpu_atpx {  static struct amdgpu_atpx_priv {  	bool atpx_detected; +	bool bridge_pm_usable;  	/* handle for device - and atpx */  	acpi_handle dhandle;  	acpi_handle other_handle; @@ -205,7 +206,11 @@ static int amdgpu_atpx_validate(struct amdgpu_atpx *atpx)  	atpx->is_hybrid = false;  	if (valid_bits & ATPX_MS_HYBRID_GFX_SUPPORTED) {  		printk("ATPX Hybrid Graphics\n"); -		atpx->functions.power_cntl = false; +		/* +		 * Disable legacy PM methods only when pcie port PM is usable, +		 * otherwise the device might fail to power off or power on. +		 */ +		atpx->functions.power_cntl = !amdgpu_atpx_priv.bridge_pm_usable;  		atpx->is_hybrid = true;  	} @@ -480,6 +485,7 @@ static int amdgpu_atpx_power_state(enum vga_switcheroo_client_id id,   */  static bool amdgpu_atpx_pci_probe_handle(struct pci_dev *pdev)  { +	struct pci_dev *parent_pdev = pci_upstream_bridge(pdev);  	acpi_handle dhandle, atpx_handle;  	acpi_status status; @@ -494,6 +500,7 @@ static bool amdgpu_atpx_pci_probe_handle(struct pci_dev *pdev)  	}  	amdgpu_atpx_priv.dhandle = dhandle;  	amdgpu_atpx_priv.atpx.handle = atpx_handle; +	amdgpu_atpx_priv.bridge_pm_usable = parent_pdev && parent_pdev->bridge_d3;  	return true;  } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c index 651115dcce12..c02db01f6583 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c @@ -132,7 +132,7 @@ static int amdgpu_bo_list_set(struct amdgpu_device *adev,  		entry->priority = min(info[i].bo_priority,  				      AMDGPU_BO_LIST_MAX_PRIORITY);  		entry->tv.bo = &entry->robj->tbo; -		entry->tv.shared = true; +		entry->tv.shared = !entry->robj->prime_shared_count;  		if (entry->robj->prefered_domains == AMDGPU_GEM_DOMAIN_GDS)  			gds_obj = entry->robj; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c index 7a8bfa34682f..662976292535 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c @@ -795,10 +795,19 @@ static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device,  		if (!adev->pm.fw) {  			switch (adev->asic_type) {  			case CHIP_TOPAZ: -				strcpy(fw_name, "amdgpu/topaz_smc.bin"); +				if (((adev->pdev->device == 0x6900) && (adev->pdev->revision == 0x81)) || +				    ((adev->pdev->device == 0x6900) && (adev->pdev->revision == 0x83)) || +				    ((adev->pdev->device == 0x6907) && (adev->pdev->revision == 0x87))) +					strcpy(fw_name, "amdgpu/topaz_k_smc.bin"); +				else +					strcpy(fw_name, "amdgpu/topaz_smc.bin");  				break;  			case CHIP_TONGA: -				strcpy(fw_name, "amdgpu/tonga_smc.bin"); +				if (((adev->pdev->device == 0x6939) && (adev->pdev->revision == 0xf1)) || +				    ((adev->pdev->device == 0x6938) && (adev->pdev->revision == 0xf1))) +					strcpy(fw_name, "amdgpu/tonga_k_smc.bin"); +				else +					strcpy(fw_name, "amdgpu/tonga_smc.bin");  				break;  			case CHIP_FIJI:  				strcpy(fw_name, "amdgpu/fiji_smc.bin"); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c index e3281d4e3e41..086aa5c9c634 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c @@ -769,7 +769,7 @@ static void amdgpu_connector_unregister(struct drm_connector *connector)  {  	struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector); -	if (amdgpu_connector->ddc_bus->has_aux) { +	if (amdgpu_connector->ddc_bus && amdgpu_connector->ddc_bus->has_aux) {  		drm_dp_aux_unregister(&amdgpu_connector->ddc_bus->aux);  		amdgpu_connector->ddc_bus->has_aux = false;  	} diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index b0f6e6957536..82dc8d20e28a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -519,7 +519,8 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p,  		r = ttm_eu_reserve_buffers(&p->ticket, &p->validated, true,  					   &duplicates);  		if (unlikely(r != 0)) { -			DRM_ERROR("ttm_eu_reserve_buffers failed.\n"); +			if (r != -ERESTARTSYS) +				DRM_ERROR("ttm_eu_reserve_buffers failed.\n");  			goto error_free_pages;  		} diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index b4f4a9239069..3161d77bf299 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -658,12 +658,10 @@ static bool amdgpu_vpost_needed(struct amdgpu_device *adev)  		return false;  	if (amdgpu_passthrough(adev)) { -		/* for FIJI: In whole GPU pass-through virtualization case -		 * old smc fw won't clear some registers (e.g. MEM_SIZE, BIOS_SCRATCH) -		 * so amdgpu_card_posted return false and driver will incorrectly skip vPost. -		 * but if we force vPost do in pass-through case, the driver reload will hang. -		 * whether doing vPost depends on amdgpu_card_posted if smc version is above -		 * 00160e00 for FIJI. +		/* for FIJI: In whole GPU pass-through virtualization case, after VM reboot +		 * some old smc fw still need driver do vPost otherwise gpu hang, while +		 * those smc fw version above 22.15 doesn't have this flaw, so we force +		 * vpost executed for smc version below 22.15  		 */  		if (adev->asic_type == CHIP_FIJI) {  			int err; @@ -674,22 +672,11 @@ static bool amdgpu_vpost_needed(struct amdgpu_device *adev)  				return true;  			fw_ver = *((uint32_t *)adev->pm.fw->data + 69); -			if (fw_ver >= 0x00160e00) -				return !amdgpu_card_posted(adev); +			if (fw_ver < 0x00160e00) +				return true;  		} -	} else { -		/* in bare-metal case, amdgpu_card_posted return false -		 * after system reboot/boot, and return true if driver -		 * reloaded. -		 * we shouldn't do vPost after driver reload otherwise GPU -		 * could hang. -		 */ -		if (amdgpu_card_posted(adev)) -			return false;  	} - -	/* we assume vPost is neede for all other cases */ -	return true; +	return !amdgpu_card_posted(adev);  }  /** @@ -1959,6 +1946,7 @@ int amdgpu_device_suspend(struct drm_device *dev, bool suspend, bool fbcon)  	/* evict remaining vram memory */  	amdgpu_bo_evict_vram(adev); +	amdgpu_atombios_scratch_regs_save(adev);  	pci_save_state(dev->pdev);  	if (suspend) {  		/* Shut down the device */ @@ -2010,6 +1998,7 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon)  			return r;  		}  	} +	amdgpu_atombios_scratch_regs_restore(adev);  	/* post card */  	if (!amdgpu_card_posted(adev) || !resume) { @@ -2268,8 +2257,6 @@ int amdgpu_gpu_reset(struct amdgpu_device *adev)  	}  	if (need_full_reset) { -		/* save scratch */ -		amdgpu_atombios_scratch_regs_save(adev);  		r = amdgpu_suspend(adev);  retry: @@ -2279,8 +2266,9 @@ retry:  			amdgpu_display_stop_mc_access(adev, &save);  			amdgpu_wait_for_idle(adev, AMD_IP_BLOCK_TYPE_GMC);  		} - +		amdgpu_atombios_scratch_regs_save(adev);  		r = amdgpu_asic_reset(adev); +		amdgpu_atombios_scratch_regs_restore(adev);  		/* post card */  		amdgpu_atom_asic_init(adev->mode_info.atom_context); @@ -2288,8 +2276,6 @@ retry:  			dev_info(adev->dev, "GPU reset succeeded, trying to resume\n");  			r = amdgpu_resume(adev);  		} -		/* restore scratch */ -		amdgpu_atombios_scratch_regs_restore(adev);  	}  	if (!r) {  		amdgpu_irq_gpu_reset_resume_helper(adev); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index 71ed27eb3dde..02ff0747197c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -735,8 +735,20 @@ static struct pci_driver amdgpu_kms_pci_driver = {  static int __init amdgpu_init(void)  { -	amdgpu_sync_init(); -	amdgpu_fence_slab_init(); +	int r; + +	r = amdgpu_sync_init(); +	if (r) +		goto error_sync; + +	r = amdgpu_fence_slab_init(); +	if (r) +		goto error_fence; + +	r = amd_sched_fence_slab_init(); +	if (r) +		goto error_sched; +  	if (vgacon_text_force()) {  		DRM_ERROR("VGACON disables amdgpu kernel modesetting.\n");  		return -EINVAL; @@ -748,6 +760,15 @@ static int __init amdgpu_init(void)  	amdgpu_register_atpx_handler();  	/* let modprobe override vga console setting */  	return drm_pci_init(driver, pdriver); + +error_sched: +	amdgpu_fence_slab_fini(); + +error_fence: +	amdgpu_sync_fini(); + +error_sync: +	return r;  }  static void __exit amdgpu_exit(void) @@ -756,6 +777,7 @@ static void __exit amdgpu_exit(void)  	drm_pci_exit(driver, pdriver);  	amdgpu_unregister_atpx_handler();  	amdgpu_sync_fini(); +	amd_sched_fence_slab_fini();  	amdgpu_fence_slab_fini();  } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c index 3a2e42f4b897..77b34ec92632 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c @@ -68,6 +68,7 @@ int amdgpu_fence_slab_init(void)  void amdgpu_fence_slab_fini(void)  { +	rcu_barrier();  	kmem_cache_destroy(amdgpu_fence_slab);  }  /* diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c index 278708f5a744..9fa809876339 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c @@ -239,6 +239,7 @@ int amdgpu_irq_init(struct amdgpu_device *adev)  	if (r) {  		adev->irq.installed = false;  		flush_work(&adev->hotplug_work); +		cancel_work_sync(&adev->reset_work);  		return r;  	} @@ -264,6 +265,7 @@ void amdgpu_irq_fini(struct amdgpu_device *adev)  		if (adev->irq.msi_enabled)  			pci_disable_msi(adev->pdev);  		flush_work(&adev->hotplug_work); +		cancel_work_sync(&adev->reset_work);  	}  	for (i = 0; i < AMDGPU_MAX_IRQ_SRC_ID; ++i) { diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index c2c7fb140338..3938fca1ea8e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c @@ -99,6 +99,8 @@ int amdgpu_driver_load_kms(struct drm_device *dev, unsigned long flags)  	if ((amdgpu_runtime_pm != 0) &&  	    amdgpu_has_atpx() && +	    (amdgpu_is_atpx_hybrid() || +	     amdgpu_has_atpx_dgpu_power_cntl()) &&  	    ((flags & AMD_IS_APU) == 0))  		flags |= AMD_IS_PX; @@ -459,10 +461,8 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file  		/* return all clocks in KHz */  		dev_info.gpu_counter_freq = amdgpu_asic_get_xclk(adev) * 10;  		if (adev->pm.dpm_enabled) { -			dev_info.max_engine_clock = -				adev->pm.dpm.dyn_state.max_clock_voltage_on_ac.sclk * 10; -			dev_info.max_memory_clock = -				adev->pm.dpm.dyn_state.max_clock_voltage_on_ac.mclk * 10; +			dev_info.max_engine_clock = amdgpu_dpm_get_sclk(adev, false) * 10; +			dev_info.max_memory_clock = amdgpu_dpm_get_mclk(adev, false) * 10;  		} else {  			dev_info.max_engine_clock = adev->pm.default_sclk * 10;  			dev_info.max_memory_clock = adev->pm.default_mclk * 10; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c index 7700dc22f243..3826d5aea0a6 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c @@ -74,20 +74,36 @@ amdgpu_gem_prime_import_sg_table(struct drm_device *dev,  	if (ret)  		return ERR_PTR(ret); +	bo->prime_shared_count = 1;  	return &bo->gem_base;  }  int amdgpu_gem_prime_pin(struct drm_gem_object *obj)  {  	struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj); -	int ret = 0; +	long ret = 0;  	ret = amdgpu_bo_reserve(bo, false);  	if (unlikely(ret != 0))  		return ret; +	/* +	 * Wait for all shared fences to complete before we switch to future +	 * use of exclusive fence on this prime shared bo. +	 */ +	ret = reservation_object_wait_timeout_rcu(bo->tbo.resv, true, false, +						  MAX_SCHEDULE_TIMEOUT); +	if (unlikely(ret < 0)) { +		DRM_DEBUG_PRIME("Fence wait failed: %li\n", ret); +		amdgpu_bo_unreserve(bo); +		return ret; +	} +  	/* pin buffer into GTT */  	ret = amdgpu_bo_pin(bo, AMDGPU_GEM_DOMAIN_GTT, NULL); +	if (likely(ret == 0)) +		bo->prime_shared_count++; +  	amdgpu_bo_unreserve(bo);  	return ret;  } @@ -102,6 +118,8 @@ void amdgpu_gem_prime_unpin(struct drm_gem_object *obj)  		return;  	amdgpu_bo_unpin(bo); +	if (bo->prime_shared_count) +		bo->prime_shared_count--;  	amdgpu_bo_unreserve(bo);  } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index 06f24322e7c3..968c4260d7a7 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -1758,5 +1758,6 @@ void amdgpu_vm_manager_fini(struct amdgpu_device *adev)  		fence_put(adev->vm_manager.ids[i].first);  		amdgpu_sync_free(&adev->vm_manager.ids[i].active);  		fence_put(id->flushed_updates); +		fence_put(id->last_flush);  	}  } diff --git a/drivers/gpu/drm/amd/amdgpu/ci_dpm.c b/drivers/gpu/drm/amd/amdgpu/ci_dpm.c index 1d8c375a3561..5be788b269e2 100644 --- a/drivers/gpu/drm/amd/amdgpu/ci_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/ci_dpm.c @@ -4075,7 +4075,7 @@ static int ci_enable_uvd_dpm(struct amdgpu_device *adev, bool enable)  							  pi->dpm_level_enable_mask.mclk_dpm_enable_mask);  		}  	} else { -		if (pi->last_mclk_dpm_enable_mask & 0x1) { +		if (pi->uvd_enabled) {  			pi->uvd_enabled = false;  			pi->dpm_level_enable_mask.mclk_dpm_enable_mask |= 1;  			amdgpu_ci_send_msg_to_smc_with_parameter(adev, @@ -6236,6 +6236,8 @@ static int ci_dpm_sw_fini(void *handle)  {  	struct amdgpu_device *adev = (struct amdgpu_device *)handle; +	flush_work(&adev->pm.dpm.thermal.work); +  	mutex_lock(&adev->pm.mutex);  	amdgpu_pm_sysfs_fini(adev);  	ci_dpm_fini(adev); diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c index 4108c686aa7c..9260caef74fa 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c @@ -3151,10 +3151,6 @@ static int dce_v10_0_hw_fini(void *handle)  static int dce_v10_0_suspend(void *handle)  { -	struct amdgpu_device *adev = (struct amdgpu_device *)handle; - -	amdgpu_atombios_scratch_regs_save(adev); -  	return dce_v10_0_hw_fini(handle);  } @@ -3165,8 +3161,6 @@ static int dce_v10_0_resume(void *handle)  	ret = dce_v10_0_hw_init(handle); -	amdgpu_atombios_scratch_regs_restore(adev); -  	/* turn on the BL */  	if (adev->mode_info.bl_encoder) {  		u8 bl_level = amdgpu_display_backlight_get_level(adev, diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c index f264b8f17ad1..367739bd1927 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c @@ -3215,10 +3215,6 @@ static int dce_v11_0_hw_fini(void *handle)  static int dce_v11_0_suspend(void *handle)  { -	struct amdgpu_device *adev = (struct amdgpu_device *)handle; - -	amdgpu_atombios_scratch_regs_save(adev); -  	return dce_v11_0_hw_fini(handle);  } @@ -3229,8 +3225,6 @@ static int dce_v11_0_resume(void *handle)  	ret = dce_v11_0_hw_init(handle); -	amdgpu_atombios_scratch_regs_restore(adev); -  	/* turn on the BL */  	if (adev->mode_info.bl_encoder) {  		u8 bl_level = amdgpu_display_backlight_get_level(adev, diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c index b948d6cb1399..15f9fc0514b2 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c @@ -2482,10 +2482,6 @@ static int dce_v6_0_hw_fini(void *handle)  static int dce_v6_0_suspend(void *handle)  { -	struct amdgpu_device *adev = (struct amdgpu_device *)handle; - -	amdgpu_atombios_scratch_regs_save(adev); -  	return dce_v6_0_hw_fini(handle);  } @@ -2496,8 +2492,6 @@ static int dce_v6_0_resume(void *handle)  	ret = dce_v6_0_hw_init(handle); -	amdgpu_atombios_scratch_regs_restore(adev); -  	/* turn on the BL */  	if (adev->mode_info.bl_encoder) {  		u8 bl_level = amdgpu_display_backlight_get_level(adev, diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c index 5966166ec94c..8c4d808db0f1 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c @@ -3033,10 +3033,6 @@ static int dce_v8_0_hw_fini(void *handle)  static int dce_v8_0_suspend(void *handle)  { -	struct amdgpu_device *adev = (struct amdgpu_device *)handle; - -	amdgpu_atombios_scratch_regs_save(adev); -  	return dce_v8_0_hw_fini(handle);  } @@ -3047,8 +3043,6 @@ static int dce_v8_0_resume(void *handle)  	ret = dce_v8_0_hw_init(handle); -	amdgpu_atombios_scratch_regs_restore(adev); -  	/* turn on the BL */  	if (adev->mode_info.bl_encoder) {  		u8 bl_level = amdgpu_display_backlight_get_level(adev, diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c index ee6a48a09214..bb97182dc749 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c @@ -640,7 +640,6 @@ static const u32 stoney_mgcg_cgcg_init[] =  	mmCP_MEM_SLP_CNTL, 0xffffffff, 0x00020201,  	mmRLC_MEM_SLP_CNTL, 0xffffffff, 0x00020201,  	mmCGTS_SM_CTRL_REG, 0xffffffff, 0x96940200, -	mmATC_MISC_CG, 0xffffffff, 0x000c0200,  };  static void gfx_v8_0_set_ring_funcs(struct amdgpu_device *adev); diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c index c22ef140a542..a16b2201d52c 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c @@ -100,6 +100,7 @@ static const u32 cz_mgcg_cgcg_init[] =  static const u32 stoney_mgcg_cgcg_init[] =  { +	mmATC_MISC_CG, 0xffffffff, 0x000c0200,  	mmMC_MEM_POWER_LS, 0xffffffff, 0x00000104  }; diff --git a/drivers/gpu/drm/amd/amdgpu/kv_dpm.c b/drivers/gpu/drm/amd/amdgpu/kv_dpm.c index f8618a3881a8..71d2856222fa 100644 --- a/drivers/gpu/drm/amd/amdgpu/kv_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/kv_dpm.c @@ -3063,6 +3063,8 @@ static int kv_dpm_sw_fini(void *handle)  {  	struct amdgpu_device *adev = (struct amdgpu_device *)handle; +	flush_work(&adev->pm.dpm.thermal.work); +  	mutex_lock(&adev->pm.mutex);  	amdgpu_pm_sysfs_fini(adev);  	kv_dpm_fini(adev); diff --git a/drivers/gpu/drm/amd/amdgpu/si_dpm.c b/drivers/gpu/drm/amd/amdgpu/si_dpm.c index 3de7bca5854b..d6f85b1a0b93 100644 --- a/drivers/gpu/drm/amd/amdgpu/si_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/si_dpm.c @@ -3477,6 +3477,49 @@ static void si_apply_state_adjust_rules(struct amdgpu_device *adev,  	int i;  	struct si_dpm_quirk *p = si_dpm_quirk_list; +	/* limit all SI kickers */ +	if (adev->asic_type == CHIP_PITCAIRN) { +		if ((adev->pdev->revision == 0x81) || +		    (adev->pdev->device == 0x6810) || +		    (adev->pdev->device == 0x6811) || +		    (adev->pdev->device == 0x6816) || +		    (adev->pdev->device == 0x6817) || +		    (adev->pdev->device == 0x6806)) +			max_mclk = 120000; +	} else if (adev->asic_type == CHIP_VERDE) { +		if ((adev->pdev->revision == 0x81) || +		    (adev->pdev->revision == 0x83) || +		    (adev->pdev->revision == 0x87) || +		    (adev->pdev->device == 0x6820) || +		    (adev->pdev->device == 0x6821) || +		    (adev->pdev->device == 0x6822) || +		    (adev->pdev->device == 0x6823) || +		    (adev->pdev->device == 0x682A) || +		    (adev->pdev->device == 0x682B)) { +			max_sclk = 75000; +			max_mclk = 80000; +		} +	} else if (adev->asic_type == CHIP_OLAND) { +		if ((adev->pdev->revision == 0xC7) || +		    (adev->pdev->revision == 0x80) || +		    (adev->pdev->revision == 0x81) || +		    (adev->pdev->revision == 0x83) || +		    (adev->pdev->device == 0x6604) || +		    (adev->pdev->device == 0x6605)) { +			max_sclk = 75000; +			max_mclk = 80000; +		} +	} else if (adev->asic_type == CHIP_HAINAN) { +		if ((adev->pdev->revision == 0x81) || +		    (adev->pdev->revision == 0x83) || +		    (adev->pdev->revision == 0xC3) || +		    (adev->pdev->device == 0x6664) || +		    (adev->pdev->device == 0x6665) || +		    (adev->pdev->device == 0x6667)) { +			max_sclk = 75000; +			max_mclk = 80000; +		} +	}  	/* Apply dpm quirks */  	while (p && p->chip_device != 0) {  		if (adev->pdev->vendor == p->chip_vendor && @@ -3489,22 +3532,6 @@ static void si_apply_state_adjust_rules(struct amdgpu_device *adev,  		}  		++p;  	} -	/* limit mclk on all R7 370 parts for stability */ -	if (adev->pdev->device == 0x6811 && -	    adev->pdev->revision == 0x81) -		max_mclk = 120000; -	/* limit sclk/mclk on Jet parts for stability */ -	if (adev->pdev->device == 0x6665 && -	    adev->pdev->revision == 0xc3) { -		max_sclk = 75000; -		max_mclk = 80000; -	} -	/* Limit clocks for some HD8600 parts */ -	if (adev->pdev->device == 0x6660 && -	    adev->pdev->revision == 0x83) { -		max_sclk = 75000; -		max_mclk = 80000; -	}  	if (rps->vce_active) {  		rps->evclk = adev->pm.dpm.vce_states[adev->pm.dpm.vce_level].evclk; @@ -7777,6 +7804,8 @@ static int si_dpm_sw_fini(void *handle)  {  	struct amdgpu_device *adev = (struct amdgpu_device *)handle; +	flush_work(&adev->pm.dpm.thermal.work); +  	mutex_lock(&adev->pm.mutex);  	amdgpu_pm_sysfs_fini(adev);  	si_dpm_fini(adev); diff --git a/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c b/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c index 8533269ec160..6feed726e299 100644 --- a/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c @@ -52,6 +52,8 @@  #define VCE_V3_0_STACK_SIZE	(64 * 1024)  #define VCE_V3_0_DATA_SIZE	((16 * 1024 * AMDGPU_MAX_VCE_HANDLES) + (52 * 1024)) +#define FW_52_8_3	((52 << 24) | (8 << 16) | (3 << 8)) +  static void vce_v3_0_mc_resume(struct amdgpu_device *adev, int idx);  static void vce_v3_0_set_ring_funcs(struct amdgpu_device *adev);  static void vce_v3_0_set_irq_funcs(struct amdgpu_device *adev); @@ -382,6 +384,10 @@ static int vce_v3_0_sw_init(void *handle)  	if (r)  		return r; +	/* 52.8.3 required for 3 ring support */ +	if (adev->vce.fw_version < FW_52_8_3) +		adev->vce.num_rings = 2; +  	r = amdgpu_vce_resume(adev);  	if (r)  		return r; diff --git a/drivers/gpu/drm/amd/amdgpu/vi.c b/drivers/gpu/drm/amd/amdgpu/vi.c index c0d9aad7126f..f62f1a74f890 100644 --- a/drivers/gpu/drm/amd/amdgpu/vi.c +++ b/drivers/gpu/drm/amd/amdgpu/vi.c @@ -80,7 +80,9 @@  #include "dce_virtual.h"  MODULE_FIRMWARE("amdgpu/topaz_smc.bin"); +MODULE_FIRMWARE("amdgpu/topaz_k_smc.bin");  MODULE_FIRMWARE("amdgpu/tonga_smc.bin"); +MODULE_FIRMWARE("amdgpu/tonga_k_smc.bin");  MODULE_FIRMWARE("amdgpu/fiji_smc.bin");  MODULE_FIRMWARE("amdgpu/polaris10_smc.bin");  MODULE_FIRMWARE("amdgpu/polaris10_smc_sk.bin"); @@ -1651,7 +1653,7 @@ static int vi_common_early_init(void *handle)  			AMD_CG_SUPPORT_SDMA_MGCG |  			AMD_CG_SUPPORT_SDMA_LS |  			AMD_CG_SUPPORT_VCE_MGCG; -		adev->pg_flags |= AMD_PG_SUPPORT_GFX_PG | +		adev->pg_flags = AMD_PG_SUPPORT_GFX_PG |  			AMD_PG_SUPPORT_GFX_SMG |  			AMD_PG_SUPPORT_GFX_PIPELINE |  			AMD_PG_SUPPORT_UVD |  | 

