Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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

Fixes for radeon and amdgpu for 4.9:
- allow an additional reg in the SI reg checker
- fix thermal sensor readback on CZ/ST
- misc bug fixes

* 'drm-next-4.9' of git://people.freedesktop.org/~agd5f/linux: (21 commits)
  drm/amd/powerplay: fix bug stop dpm can't work on Vi.
  drm/amd/powerplay: notify smu no display by default.
  drm/amdgpu/dpm: implement thermal sensor for CZ/ST
  drm/amdgpu/powerplay: implement thermal sensor for CZ/ST
  drm/amdgpu: disable smu hw first on tear down
  drm/amdgpu: fix amdgpu_need_full_reset (v2)
  drm/amdgpu/si_dpm: Limit clocks on HD86xx part
  drm/amd/powerplay: fix static checker warnings in smu7_hwmgr.c
  drm/amdgpu: potential NULL dereference in debugfs code
  drm/amd/powerplay: fix static checker warnings in smu7_hwmgr.c
  drm/amd/powerplay: fix static checker warnings in iceland_smc.c
  drm/radeon: change vblank_time's calculation method to reduce computational error.
  drm/amdgpu: change vblank_time's calculation method to reduce computational error.
  drm/amdgpu: clarify UVD/VCE special handling for CG
  drm/amd/amdgpu: enable clockgating only after late init
  drm/radeon: allow TA_CS_BC_BASE_ADDR on SI
  drm/amdgpu: initialize the context reset_counter in amdgpu_ctx_init
  drm/amdgpu/gfx8: fix CGCG_CGLS handling
  drm/radeon: fix modeset tear down code
  drm/radeon: fix up dp aux tear down (v2)
  ...
parents 69405d3d f28a9b65
Loading
Loading
Loading
Loading
+12 −1
Original line number Diff line number Diff line
@@ -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,
};
+3 −0
Original line number Diff line number Diff line
@@ -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];
+52 −17
Original line number Diff line number Diff line
@@ -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,6 +2099,7 @@ 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_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);
@@ -2102,13 +2129,21 @@ 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) {
	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;
}

+8 −6
Original line number Diff line number Diff line
@@ -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;
			}
		}
+2 −2
Original line number Diff line number Diff line
@@ -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;
Loading