diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu')
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c | 13 | ||||
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c | 3 | ||||
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 69 | ||||
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.c | 14 | ||||
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 5 | ||||
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c | 4 | ||||
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 7 | ||||
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/cz_dpm.c | 8 | ||||
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/dce_v10_0.c | 12 | ||||
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c | 30 | ||||
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c | 13 | ||||
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c | 14 | ||||
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/si_dpm.c | 6 | ||||
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/tonga_ih.c | 14 | ||||
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c | 14 | ||||
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/vce_v3_0.c | 15 | 
16 files changed, 151 insertions, 90 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c index 2e3a0543760d..e3281d4e3e41 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c @@ -765,7 +765,7 @@ amdgpu_connector_lvds_detect(struct drm_connector *connector, bool force)  	return ret;  } -static void amdgpu_connector_destroy(struct drm_connector *connector) +static void amdgpu_connector_unregister(struct drm_connector *connector)  {  	struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector); @@ -773,6 +773,12 @@ static void amdgpu_connector_destroy(struct drm_connector *connector)  		drm_dp_aux_unregister(&amdgpu_connector->ddc_bus->aux);  		amdgpu_connector->ddc_bus->has_aux = false;  	} +} + +static void amdgpu_connector_destroy(struct drm_connector *connector) +{ +	struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector); +  	amdgpu_connector_free_edid(connector);  	kfree(amdgpu_connector->con_priv);  	drm_connector_unregister(connector); @@ -826,6 +832,7 @@ static const struct drm_connector_funcs amdgpu_connector_lvds_funcs = {  	.dpms = drm_helper_connector_dpms,  	.detect = amdgpu_connector_lvds_detect,  	.fill_modes = drm_helper_probe_single_connector_modes, +	.early_unregister = amdgpu_connector_unregister,  	.destroy = amdgpu_connector_destroy,  	.set_property = amdgpu_connector_set_lcd_property,  }; @@ -936,6 +943,7 @@ static const struct drm_connector_funcs amdgpu_connector_vga_funcs = {  	.dpms = drm_helper_connector_dpms,  	.detect = amdgpu_connector_vga_detect,  	.fill_modes = drm_helper_probe_single_connector_modes, +	.early_unregister = amdgpu_connector_unregister,  	.destroy = amdgpu_connector_destroy,  	.set_property = amdgpu_connector_set_property,  }; @@ -1203,6 +1211,7 @@ static const struct drm_connector_funcs amdgpu_connector_dvi_funcs = {  	.detect = amdgpu_connector_dvi_detect,  	.fill_modes = drm_helper_probe_single_connector_modes,  	.set_property = amdgpu_connector_set_property, +	.early_unregister = amdgpu_connector_unregister,  	.destroy = amdgpu_connector_destroy,  	.force = amdgpu_connector_dvi_force,  }; @@ -1493,6 +1502,7 @@ static const struct drm_connector_funcs amdgpu_connector_dp_funcs = {  	.detect = amdgpu_connector_dp_detect,  	.fill_modes = drm_helper_probe_single_connector_modes,  	.set_property = amdgpu_connector_set_property, +	.early_unregister = amdgpu_connector_unregister,  	.destroy = amdgpu_connector_destroy,  	.force = amdgpu_connector_dvi_force,  }; @@ -1502,6 +1512,7 @@ static const struct drm_connector_funcs amdgpu_connector_edp_funcs = {  	.detect = amdgpu_connector_dp_detect,  	.fill_modes = drm_helper_probe_single_connector_modes,  	.set_property = amdgpu_connector_set_lcd_property, +	.early_unregister = amdgpu_connector_unregister,  	.destroy = amdgpu_connector_destroy,  	.force = amdgpu_connector_dvi_force,  }; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c index e203e5561107..a5e2fcbef0f0 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c @@ -43,6 +43,9 @@ static int amdgpu_ctx_init(struct amdgpu_device *adev, struct amdgpu_ctx *ctx)  		ctx->rings[i].sequence = 1;  		ctx->rings[i].fences = &ctx->fences[amdgpu_sched_jobs * i];  	} + +	ctx->reset_counter = atomic_read(&adev->gpu_reset_counter); +  	/* create context entity for each ring */  	for (i = 0; i < adev->num_rings; i++) {  		struct amdgpu_ring *ring = adev->rings[i]; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 7dbe85d67d26..b4f4a9239069 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -1408,16 +1408,6 @@ static int amdgpu_late_init(struct amdgpu_device *adev)  	for (i = 0; i < adev->num_ip_blocks; i++) {  		if (!adev->ip_block_status[i].valid)  			continue; -		if (adev->ip_blocks[i].type == AMD_IP_BLOCK_TYPE_UVD || -			adev->ip_blocks[i].type == AMD_IP_BLOCK_TYPE_VCE) -			continue; -		/* enable clockgating to save power */ -		r = adev->ip_blocks[i].funcs->set_clockgating_state((void *)adev, -								    AMD_CG_STATE_GATE); -		if (r) { -			DRM_ERROR("set_clockgating_state(gate) of IP block <%s> failed %d\n", adev->ip_blocks[i].funcs->name, r); -			return r; -		}  		if (adev->ip_blocks[i].funcs->late_init) {  			r = adev->ip_blocks[i].funcs->late_init((void *)adev);  			if (r) { @@ -1426,6 +1416,18 @@ static int amdgpu_late_init(struct amdgpu_device *adev)  			}  			adev->ip_block_status[i].late_initialized = true;  		} +		/* skip CG for VCE/UVD, it's handled specially */ +		if (adev->ip_blocks[i].type != AMD_IP_BLOCK_TYPE_UVD && +		    adev->ip_blocks[i].type != AMD_IP_BLOCK_TYPE_VCE) { +			/* enable clockgating to save power */ +			r = adev->ip_blocks[i].funcs->set_clockgating_state((void *)adev, +									    AMD_CG_STATE_GATE); +			if (r) { +				DRM_ERROR("set_clockgating_state(gate) of IP block <%s> failed %d\n", +					  adev->ip_blocks[i].funcs->name, r); +				return r; +			} +		}  	}  	return 0; @@ -1435,6 +1437,30 @@ static int amdgpu_fini(struct amdgpu_device *adev)  {  	int i, r; +	/* need to disable SMC first */ +	for (i = 0; i < adev->num_ip_blocks; i++) { +		if (!adev->ip_block_status[i].hw) +			continue; +		if (adev->ip_blocks[i].type == AMD_IP_BLOCK_TYPE_SMC) { +			/* ungate blocks before hw fini so that we can shutdown the blocks safely */ +			r = adev->ip_blocks[i].funcs->set_clockgating_state((void *)adev, +									    AMD_CG_STATE_UNGATE); +			if (r) { +				DRM_ERROR("set_clockgating_state(ungate) of IP block <%s> failed %d\n", +					  adev->ip_blocks[i].funcs->name, r); +				return r; +			} +			r = adev->ip_blocks[i].funcs->hw_fini((void *)adev); +			/* XXX handle errors */ +			if (r) { +				DRM_DEBUG("hw_fini of IP block <%s> failed %d\n", +					  adev->ip_blocks[i].funcs->name, r); +			} +			adev->ip_block_status[i].hw = false; +			break; +		} +	} +  	for (i = adev->num_ip_blocks - 1; i >= 0; i--) {  		if (!adev->ip_block_status[i].hw)  			continue; @@ -2073,7 +2099,8 @@ static bool amdgpu_check_soft_reset(struct amdgpu_device *adev)  		if (!adev->ip_block_status[i].valid)  			continue;  		if (adev->ip_blocks[i].funcs->check_soft_reset) -			adev->ip_blocks[i].funcs->check_soft_reset(adev); +			adev->ip_block_status[i].hang = +				adev->ip_blocks[i].funcs->check_soft_reset(adev);  		if (adev->ip_block_status[i].hang) {  			DRM_INFO("IP block:%d is hang!\n", i);  			asic_hang = true; @@ -2102,12 +2129,20 @@ static int amdgpu_pre_soft_reset(struct amdgpu_device *adev)  static bool amdgpu_need_full_reset(struct amdgpu_device *adev)  { -	if (adev->ip_block_status[AMD_IP_BLOCK_TYPE_GMC].hang || -	    adev->ip_block_status[AMD_IP_BLOCK_TYPE_SMC].hang || -	    adev->ip_block_status[AMD_IP_BLOCK_TYPE_ACP].hang || -	    adev->ip_block_status[AMD_IP_BLOCK_TYPE_DCE].hang) { -		DRM_INFO("Some block need full reset!\n"); -		return true; +	int i; + +	for (i = 0; i < adev->num_ip_blocks; i++) { +		if (!adev->ip_block_status[i].valid) +			continue; +		if ((adev->ip_blocks[i].type == AMD_IP_BLOCK_TYPE_GMC) || +		    (adev->ip_blocks[i].type == AMD_IP_BLOCK_TYPE_SMC) || +		    (adev->ip_blocks[i].type == AMD_IP_BLOCK_TYPE_ACP) || +		    (adev->ip_blocks[i].type == AMD_IP_BLOCK_TYPE_DCE)) { +			if (adev->ip_block_status[i].hang) { +				DRM_INFO("Some block need full reset!\n"); +				return true; +			} +		}  	}  	return false;  } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.c index fe36caf1b7d7..14f57d9915e3 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.c @@ -113,24 +113,26 @@ void amdgpu_dpm_print_ps_status(struct amdgpu_device *adev,  	printk("\n");  } +  u32 amdgpu_dpm_get_vblank_time(struct amdgpu_device *adev)  {  	struct drm_device *dev = adev->ddev;  	struct drm_crtc *crtc;  	struct amdgpu_crtc *amdgpu_crtc; -	u32 line_time_us, vblank_lines; +	u32 vblank_in_pixels;  	u32 vblank_time_us = 0xffffffff; /* if the displays are off, vblank time is max */  	if (adev->mode_info.num_crtc && adev->mode_info.mode_config_initialized) {  		list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {  			amdgpu_crtc = to_amdgpu_crtc(crtc);  			if (crtc->enabled && amdgpu_crtc->enabled && amdgpu_crtc->hw_mode.clock) { -				line_time_us = (amdgpu_crtc->hw_mode.crtc_htotal * 1000) / -					amdgpu_crtc->hw_mode.clock; -				vblank_lines = amdgpu_crtc->hw_mode.crtc_vblank_end - +				vblank_in_pixels = +					amdgpu_crtc->hw_mode.crtc_htotal * +					(amdgpu_crtc->hw_mode.crtc_vblank_end -  					amdgpu_crtc->hw_mode.crtc_vdisplay + -					(amdgpu_crtc->v_border * 2); -				vblank_time_us = vblank_lines * line_time_us; +					(amdgpu_crtc->v_border * 2)); + +				vblank_time_us = vblank_in_pixels * 1000 / amdgpu_crtc->hw_mode.clock;  				break;  			}  		} diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c index aa074fac0c7f..f3efb1c5dae9 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c @@ -754,6 +754,10 @@ static const char *amdgpu_vram_names[] = {  int amdgpu_bo_init(struct amdgpu_device *adev)  { +	/* reserve PAT memory space to WC for VRAM */ +	arch_io_reserve_memtype_wc(adev->mc.aper_base, +				   adev->mc.aper_size); +  	/* Add an MTRR for the VRAM */  	adev->mc.vram_mtrr = arch_phys_wc_add(adev->mc.aper_base,  					      adev->mc.aper_size); @@ -769,6 +773,7 @@ void amdgpu_bo_fini(struct amdgpu_device *adev)  {  	amdgpu_ttm_fini(adev);  	arch_phys_wc_del(adev->mc.vram_mtrr); +	arch_io_free_memtype_wc(adev->mc.aper_base, adev->mc.aper_size);  }  int amdgpu_bo_fbdev_mmap(struct amdgpu_bo *bo, diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c index e1fa8731d1e2..3cb5e903cd62 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c @@ -345,8 +345,8 @@ static int amdgpu_debugfs_ring_init(struct amdgpu_device *adev,  	ent = debugfs_create_file(name,  				  S_IFREG | S_IRUGO, root,  				  ring, &amdgpu_debugfs_ring_fops); -	if (IS_ERR(ent)) -		return PTR_ERR(ent); +	if (!ent) +		return -ENOMEM;  	i_size_write(ent->d_inode, ring->ring_size + 12);  	ring->ent = ent; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index 887483b8b818..dcaf691f56b5 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c @@ -555,10 +555,13 @@ struct amdgpu_ttm_tt {  int amdgpu_ttm_tt_get_user_pages(struct ttm_tt *ttm, struct page **pages)  {  	struct amdgpu_ttm_tt *gtt = (void *)ttm; -	int write = !(gtt->userflags & AMDGPU_GEM_USERPTR_READONLY); +	unsigned int flags = 0;  	unsigned pinned = 0;  	int r; +	if (!(gtt->userflags & AMDGPU_GEM_USERPTR_READONLY)) +		flags |= FOLL_WRITE; +  	if (gtt->userflags & AMDGPU_GEM_USERPTR_ANONONLY) {  		/* check that we only use anonymous memory  		   to prevent problems with writeback */ @@ -581,7 +584,7 @@ int amdgpu_ttm_tt_get_user_pages(struct ttm_tt *ttm, struct page **pages)  		list_add(&guptask.list, >t->guptasks);  		spin_unlock(>t->guptasklock); -		r = get_user_pages(userptr, num_pages, write, 0, p, NULL); +		r = get_user_pages(userptr, num_pages, flags, p, NULL);  		spin_lock(>t->guptasklock);  		list_del(&guptask.list); diff --git a/drivers/gpu/drm/amd/amdgpu/cz_dpm.c b/drivers/gpu/drm/amd/amdgpu/cz_dpm.c index f80a0834e889..3c082e143730 100644 --- a/drivers/gpu/drm/amd/amdgpu/cz_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/cz_dpm.c @@ -1514,14 +1514,16 @@ static int cz_dpm_set_powergating_state(void *handle,  	return 0;  } -/* borrowed from KV, need future unify */  static int cz_dpm_get_temperature(struct amdgpu_device *adev)  {  	int actual_temp = 0; -	uint32_t temp = RREG32_SMC(0xC0300E0C); +	uint32_t val = RREG32_SMC(ixTHM_TCON_CUR_TMP); +	uint32_t temp = REG_GET_FIELD(val, THM_TCON_CUR_TMP, CUR_TEMP); -	if (temp) +	if (REG_GET_FIELD(val, THM_TCON_CUR_TMP, CUR_TEMP_RANGE_SEL))  		actual_temp = 1000 * ((temp / 8) - 49); +	else +		actual_temp = 1000 * (temp / 8);  	return actual_temp;  } diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c index 613ebb7ed50f..4108c686aa7c 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c @@ -3188,16 +3188,11 @@ static int dce_v10_0_wait_for_idle(void *handle)  	return 0;  } -static int dce_v10_0_check_soft_reset(void *handle) +static bool dce_v10_0_check_soft_reset(void *handle)  {  	struct amdgpu_device *adev = (struct amdgpu_device *)handle; -	if (dce_v10_0_is_display_hung(adev)) -		adev->ip_block_status[AMD_IP_BLOCK_TYPE_DCE].hang = true; -	else -		adev->ip_block_status[AMD_IP_BLOCK_TYPE_DCE].hang = false; - -	return 0; +	return dce_v10_0_is_display_hung(adev);  }  static int dce_v10_0_soft_reset(void *handle) @@ -3205,9 +3200,6 @@ static int dce_v10_0_soft_reset(void *handle)  	u32 srbm_soft_reset = 0, tmp;  	struct amdgpu_device *adev = (struct amdgpu_device *)handle; -	if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_DCE].hang) -		return 0; -  	if (dce_v10_0_is_display_hung(adev))  		srbm_soft_reset |= SRBM_SOFT_RESET__SOFT_RESET_DC_MASK; diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c index 6c6ff57b1c95..ee6a48a09214 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c @@ -4087,14 +4087,21 @@ static int gfx_v8_0_rlc_load_microcode(struct amdgpu_device *adev)  static int gfx_v8_0_rlc_resume(struct amdgpu_device *adev)  {  	int r; +	u32 tmp;  	gfx_v8_0_rlc_stop(adev);  	/* disable CG */ -	WREG32(mmRLC_CGCG_CGLS_CTRL, 0); +	tmp = RREG32(mmRLC_CGCG_CGLS_CTRL); +	tmp &= ~(RLC_CGCG_CGLS_CTRL__CGCG_EN_MASK | +		 RLC_CGCG_CGLS_CTRL__CGLS_EN_MASK); +	WREG32(mmRLC_CGCG_CGLS_CTRL, tmp);  	if (adev->asic_type == CHIP_POLARIS11 || -	    adev->asic_type == CHIP_POLARIS10) -		WREG32(mmRLC_CGCG_CGLS_CTRL_3D, 0); +	    adev->asic_type == CHIP_POLARIS10) { +		tmp = RREG32(mmRLC_CGCG_CGLS_CTRL_3D); +		tmp &= ~0x3; +		WREG32(mmRLC_CGCG_CGLS_CTRL_3D, tmp); +	}  	/* disable PG */  	WREG32(mmRLC_PG_CNTL, 0); @@ -5137,7 +5144,7 @@ static int gfx_v8_0_wait_for_idle(void *handle)  	return -ETIMEDOUT;  } -static int gfx_v8_0_check_soft_reset(void *handle) +static bool gfx_v8_0_check_soft_reset(void *handle)  {  	struct amdgpu_device *adev = (struct amdgpu_device *)handle;  	u32 grbm_soft_reset = 0, srbm_soft_reset = 0; @@ -5189,16 +5196,14 @@ static int gfx_v8_0_check_soft_reset(void *handle)  						SRBM_SOFT_RESET, SOFT_RESET_SEM, 1);  	if (grbm_soft_reset || srbm_soft_reset) { -		adev->ip_block_status[AMD_IP_BLOCK_TYPE_GFX].hang = true;  		adev->gfx.grbm_soft_reset = grbm_soft_reset;  		adev->gfx.srbm_soft_reset = srbm_soft_reset; +		return true;  	} else { -		adev->ip_block_status[AMD_IP_BLOCK_TYPE_GFX].hang = false;  		adev->gfx.grbm_soft_reset = 0;  		adev->gfx.srbm_soft_reset = 0; +		return false;  	} - -	return 0;  }  static void gfx_v8_0_inactive_hqd(struct amdgpu_device *adev, @@ -5226,7 +5231,8 @@ static int gfx_v8_0_pre_soft_reset(void *handle)  	struct amdgpu_device *adev = (struct amdgpu_device *)handle;  	u32 grbm_soft_reset = 0, srbm_soft_reset = 0; -	if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_GFX].hang) +	if ((!adev->gfx.grbm_soft_reset) && +	    (!adev->gfx.srbm_soft_reset))  		return 0;  	grbm_soft_reset = adev->gfx.grbm_soft_reset; @@ -5264,7 +5270,8 @@ static int gfx_v8_0_soft_reset(void *handle)  	u32 grbm_soft_reset = 0, srbm_soft_reset = 0;  	u32 tmp; -	if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_GFX].hang) +	if ((!adev->gfx.grbm_soft_reset) && +	    (!adev->gfx.srbm_soft_reset))  		return 0;  	grbm_soft_reset = adev->gfx.grbm_soft_reset; @@ -5334,7 +5341,8 @@ static int gfx_v8_0_post_soft_reset(void *handle)  	struct amdgpu_device *adev = (struct amdgpu_device *)handle;  	u32 grbm_soft_reset = 0, srbm_soft_reset = 0; -	if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_GFX].hang) +	if ((!adev->gfx.grbm_soft_reset) && +	    (!adev->gfx.srbm_soft_reset))  		return 0;  	grbm_soft_reset = adev->gfx.grbm_soft_reset; diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c index 1b319f5bc696..c22ef140a542 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c @@ -1099,7 +1099,7 @@ static int gmc_v8_0_wait_for_idle(void *handle)  } -static int gmc_v8_0_check_soft_reset(void *handle) +static bool gmc_v8_0_check_soft_reset(void *handle)  {  	u32 srbm_soft_reset = 0;  	struct amdgpu_device *adev = (struct amdgpu_device *)handle; @@ -1116,20 +1116,19 @@ static int gmc_v8_0_check_soft_reset(void *handle)  							SRBM_SOFT_RESET, SOFT_RESET_MC, 1);  	}  	if (srbm_soft_reset) { -		adev->ip_block_status[AMD_IP_BLOCK_TYPE_GMC].hang = true;  		adev->mc.srbm_soft_reset = srbm_soft_reset; +		return true;  	} else { -		adev->ip_block_status[AMD_IP_BLOCK_TYPE_GMC].hang = false;  		adev->mc.srbm_soft_reset = 0; +		return false;  	} -	return 0;  }  static int gmc_v8_0_pre_soft_reset(void *handle)  {  	struct amdgpu_device *adev = (struct amdgpu_device *)handle; -	if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_GMC].hang) +	if (!adev->mc.srbm_soft_reset)  		return 0;  	gmc_v8_0_mc_stop(adev, &adev->mc.save); @@ -1145,7 +1144,7 @@ static int gmc_v8_0_soft_reset(void *handle)  	struct amdgpu_device *adev = (struct amdgpu_device *)handle;  	u32 srbm_soft_reset; -	if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_GMC].hang) +	if (!adev->mc.srbm_soft_reset)  		return 0;  	srbm_soft_reset = adev->mc.srbm_soft_reset; @@ -1175,7 +1174,7 @@ static int gmc_v8_0_post_soft_reset(void *handle)  {  	struct amdgpu_device *adev = (struct amdgpu_device *)handle; -	if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_GMC].hang) +	if (!adev->mc.srbm_soft_reset)  		return 0;  	gmc_v8_0_mc_resume(adev, &adev->mc.save); diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c index f325fd86430b..a9d10941fb53 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c @@ -1268,7 +1268,7 @@ static int sdma_v3_0_wait_for_idle(void *handle)  	return -ETIMEDOUT;  } -static int sdma_v3_0_check_soft_reset(void *handle) +static bool sdma_v3_0_check_soft_reset(void *handle)  {  	struct amdgpu_device *adev = (struct amdgpu_device *)handle;  	u32 srbm_soft_reset = 0; @@ -1281,14 +1281,12 @@ static int sdma_v3_0_check_soft_reset(void *handle)  	}  	if (srbm_soft_reset) { -		adev->ip_block_status[AMD_IP_BLOCK_TYPE_SDMA].hang = true;  		adev->sdma.srbm_soft_reset = srbm_soft_reset; +		return true;  	} else { -		adev->ip_block_status[AMD_IP_BLOCK_TYPE_SDMA].hang = false;  		adev->sdma.srbm_soft_reset = 0; +		return false;  	} - -	return 0;  }  static int sdma_v3_0_pre_soft_reset(void *handle) @@ -1296,7 +1294,7 @@ static int sdma_v3_0_pre_soft_reset(void *handle)  	struct amdgpu_device *adev = (struct amdgpu_device *)handle;  	u32 srbm_soft_reset = 0; -	if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_SDMA].hang) +	if (!adev->sdma.srbm_soft_reset)  		return 0;  	srbm_soft_reset = adev->sdma.srbm_soft_reset; @@ -1315,7 +1313,7 @@ static int sdma_v3_0_post_soft_reset(void *handle)  	struct amdgpu_device *adev = (struct amdgpu_device *)handle;  	u32 srbm_soft_reset = 0; -	if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_SDMA].hang) +	if (!adev->sdma.srbm_soft_reset)  		return 0;  	srbm_soft_reset = adev->sdma.srbm_soft_reset; @@ -1335,7 +1333,7 @@ static int sdma_v3_0_soft_reset(void *handle)  	u32 srbm_soft_reset = 0;  	u32 tmp; -	if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_SDMA].hang) +	if (!adev->sdma.srbm_soft_reset)  		return 0;  	srbm_soft_reset = adev->sdma.srbm_soft_reset; diff --git a/drivers/gpu/drm/amd/amdgpu/si_dpm.c b/drivers/gpu/drm/amd/amdgpu/si_dpm.c index 8bd08925b370..3de7bca5854b 100644 --- a/drivers/gpu/drm/amd/amdgpu/si_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/si_dpm.c @@ -3499,6 +3499,12 @@ static void si_apply_state_adjust_rules(struct amdgpu_device *adev,  		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; diff --git a/drivers/gpu/drm/amd/amdgpu/tonga_ih.c b/drivers/gpu/drm/amd/amdgpu/tonga_ih.c index d127d59f953a..b4ea229bb449 100644 --- a/drivers/gpu/drm/amd/amdgpu/tonga_ih.c +++ b/drivers/gpu/drm/amd/amdgpu/tonga_ih.c @@ -373,7 +373,7 @@ static int tonga_ih_wait_for_idle(void *handle)  	return -ETIMEDOUT;  } -static int tonga_ih_check_soft_reset(void *handle) +static bool tonga_ih_check_soft_reset(void *handle)  {  	struct amdgpu_device *adev = (struct amdgpu_device *)handle;  	u32 srbm_soft_reset = 0; @@ -384,21 +384,19 @@ static int tonga_ih_check_soft_reset(void *handle)  						SOFT_RESET_IH, 1);  	if (srbm_soft_reset) { -		adev->ip_block_status[AMD_IP_BLOCK_TYPE_IH].hang = true;  		adev->irq.srbm_soft_reset = srbm_soft_reset; +		return true;  	} else { -		adev->ip_block_status[AMD_IP_BLOCK_TYPE_IH].hang = false;  		adev->irq.srbm_soft_reset = 0; +		return false;  	} - -	return 0;  }  static int tonga_ih_pre_soft_reset(void *handle)  {  	struct amdgpu_device *adev = (struct amdgpu_device *)handle; -	if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_IH].hang) +	if (!adev->irq.srbm_soft_reset)  		return 0;  	return tonga_ih_hw_fini(adev); @@ -408,7 +406,7 @@ static int tonga_ih_post_soft_reset(void *handle)  {  	struct amdgpu_device *adev = (struct amdgpu_device *)handle; -	if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_IH].hang) +	if (!adev->irq.srbm_soft_reset)  		return 0;  	return tonga_ih_hw_init(adev); @@ -419,7 +417,7 @@ static int tonga_ih_soft_reset(void *handle)  	struct amdgpu_device *adev = (struct amdgpu_device *)handle;  	u32 srbm_soft_reset; -	if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_IH].hang) +	if (!adev->irq.srbm_soft_reset)  		return 0;  	srbm_soft_reset = adev->irq.srbm_soft_reset; diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c index e0fd9f21ed95..ab3df6d75656 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c @@ -770,7 +770,7 @@ static int uvd_v6_0_wait_for_idle(void *handle)  }  #define AMDGPU_UVD_STATUS_BUSY_MASK    0xfd -static int uvd_v6_0_check_soft_reset(void *handle) +static bool uvd_v6_0_check_soft_reset(void *handle)  {  	struct amdgpu_device *adev = (struct amdgpu_device *)handle;  	u32 srbm_soft_reset = 0; @@ -782,19 +782,19 @@ static int uvd_v6_0_check_soft_reset(void *handle)  		srbm_soft_reset = REG_SET_FIELD(srbm_soft_reset, SRBM_SOFT_RESET, SOFT_RESET_UVD, 1);  	if (srbm_soft_reset) { -		adev->ip_block_status[AMD_IP_BLOCK_TYPE_UVD].hang = true;  		adev->uvd.srbm_soft_reset = srbm_soft_reset; +		return true;  	} else { -		adev->ip_block_status[AMD_IP_BLOCK_TYPE_UVD].hang = false;  		adev->uvd.srbm_soft_reset = 0; +		return false;  	} -	return 0;  } +  static int uvd_v6_0_pre_soft_reset(void *handle)  {  	struct amdgpu_device *adev = (struct amdgpu_device *)handle; -	if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_UVD].hang) +	if (!adev->uvd.srbm_soft_reset)  		return 0;  	uvd_v6_0_stop(adev); @@ -806,7 +806,7 @@ static int uvd_v6_0_soft_reset(void *handle)  	struct amdgpu_device *adev = (struct amdgpu_device *)handle;  	u32 srbm_soft_reset; -	if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_UVD].hang) +	if (!adev->uvd.srbm_soft_reset)  		return 0;  	srbm_soft_reset = adev->uvd.srbm_soft_reset; @@ -836,7 +836,7 @@ static int uvd_v6_0_post_soft_reset(void *handle)  {  	struct amdgpu_device *adev = (struct amdgpu_device *)handle; -	if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_UVD].hang) +	if (!adev->uvd.srbm_soft_reset)  		return 0;  	mdelay(5); diff --git a/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c b/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c index 3f6db4ec0102..8533269ec160 100644 --- a/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c @@ -561,7 +561,7 @@ static int vce_v3_0_wait_for_idle(void *handle)  #define  AMDGPU_VCE_STATUS_BUSY_MASK (VCE_STATUS_VCPU_REPORT_AUTO_BUSY_MASK | \  				      VCE_STATUS_VCPU_REPORT_RB0_BUSY_MASK) -static int vce_v3_0_check_soft_reset(void *handle) +static bool vce_v3_0_check_soft_reset(void *handle)  {  	struct amdgpu_device *adev = (struct amdgpu_device *)handle;  	u32 srbm_soft_reset = 0; @@ -591,16 +591,15 @@ static int vce_v3_0_check_soft_reset(void *handle)  		srbm_soft_reset = REG_SET_FIELD(srbm_soft_reset, SRBM_SOFT_RESET, SOFT_RESET_VCE1, 1);  	}  	WREG32_FIELD(GRBM_GFX_INDEX, INSTANCE_INDEX, 0); +	mutex_unlock(&adev->grbm_idx_mutex);  	if (srbm_soft_reset) { -		adev->ip_block_status[AMD_IP_BLOCK_TYPE_VCE].hang = true;  		adev->vce.srbm_soft_reset = srbm_soft_reset; +		return true;  	} else { -		adev->ip_block_status[AMD_IP_BLOCK_TYPE_VCE].hang = false;  		adev->vce.srbm_soft_reset = 0; +		return false;  	} -	mutex_unlock(&adev->grbm_idx_mutex); -	return 0;  }  static int vce_v3_0_soft_reset(void *handle) @@ -608,7 +607,7 @@ static int vce_v3_0_soft_reset(void *handle)  	struct amdgpu_device *adev = (struct amdgpu_device *)handle;  	u32 srbm_soft_reset; -	if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_VCE].hang) +	if (!adev->vce.srbm_soft_reset)  		return 0;  	srbm_soft_reset = adev->vce.srbm_soft_reset; @@ -638,7 +637,7 @@ static int vce_v3_0_pre_soft_reset(void *handle)  {  	struct amdgpu_device *adev = (struct amdgpu_device *)handle; -	if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_VCE].hang) +	if (!adev->vce.srbm_soft_reset)  		return 0;  	mdelay(5); @@ -651,7 +650,7 @@ static int vce_v3_0_post_soft_reset(void *handle)  {  	struct amdgpu_device *adev = (struct amdgpu_device *)handle; -	if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_VCE].hang) +	if (!adev->vce.srbm_soft_reset)  		return 0;  	mdelay(5);  | 

