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

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

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

A few radeon and amdgpu fixes for 4.5.  A few further fixes for the vblank
regressions in 4.4 and a couple of other minor fixes.

* 'drm-fixes-4.5' of git://people.freedesktop.org/~agd5f/linux:
  drm/amdgpu: disable direct VM updates when vm_debug is set
  amdgpu: fix NULL pointer dereference at tonga_check_states_equal
  drm/radeon/pm: adjust display configuration after powerstate
  drm/amdgpu/pm: adjust display configuration after powerstate
  drm/amdgpu/pm: add some checks for PX
  drm/amdgpu: fix locking in force performance level
  drm/amdgpu/gfx8: fix priv reg interrupt enable
  drm/amdgpu: Don't hang in amdgpu_flip_work_func on disabled crtc.
  drm/radeon: Don't hang in radeon_flip_work_func on disabled crtc. (v2)
parents 84e54c46 6378076b
Loading
Loading
Loading
Loading
+15 −3
Original line number Diff line number Diff line
@@ -72,8 +72,8 @@ static void amdgpu_flip_work_func(struct work_struct *__work)

	struct drm_crtc *crtc = &amdgpuCrtc->base;
	unsigned long flags;
	unsigned i;
	int vpos, hpos, stat, min_udelay;
	unsigned i, repcnt = 4;
	int vpos, hpos, stat, min_udelay = 0;
	struct drm_vblank_crtc *vblank = &crtc->dev->vblank[work->crtc_id];

	amdgpu_flip_wait_fence(adev, &work->excl);
@@ -96,7 +96,7 @@ static void amdgpu_flip_work_func(struct work_struct *__work)
	 * In practice this won't execute very often unless on very fast
	 * machines because the time window for this to happen is very small.
	 */
	for (;;) {
	while (amdgpuCrtc->enabled && repcnt--) {
		/* GET_DISTANCE_TO_VBLANKSTART returns distance to real vblank
		 * start in hpos, and to the "fudged earlier" vblank start in
		 * vpos.
@@ -114,10 +114,22 @@ static void amdgpu_flip_work_func(struct work_struct *__work)
		/* Sleep at least until estimated real start of hw vblank */
		spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
		min_udelay = (-hpos + 1) * max(vblank->linedur_ns / 1000, 5);
		if (min_udelay > vblank->framedur_ns / 2000) {
			/* Don't wait ridiculously long - something is wrong */
			repcnt = 0;
			break;
		}
		usleep_range(min_udelay, 2 * min_udelay);
		spin_lock_irqsave(&crtc->dev->event_lock, flags);
	};

	if (!repcnt)
		DRM_DEBUG_DRIVER("Delay problem on crtc %d: min_udelay %d, "
				 "framedur %d, linedur %d, stat %d, vpos %d, "
				 "hpos %d\n", work->crtc_id, min_udelay,
				 vblank->framedur_ns / 1000,
				 vblank->linedur_ns / 1000, stat, vpos, hpos);

	/* do the flip (mmio) */
	adev->mode_info.funcs->page_flip(adev, work->crtc_id, work->base);
	/* set the flip status */
+2 −1
Original line number Diff line number Diff line
@@ -596,7 +596,8 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data,
		break;
	}
	ttm_eu_backoff_reservation(&ticket, &list);
	if (!r && !(args->flags & AMDGPU_VM_DELAY_UPDATE))
	if (!r && !(args->flags & AMDGPU_VM_DELAY_UPDATE) &&
	    !amdgpu_vm_debug)
		amdgpu_gem_va_update_vm(adev, bo_va, args->operation);

	drm_gem_object_unreference_unlocked(gobj);
+24 −5
Original line number Diff line number Diff line
@@ -113,6 +113,10 @@ static ssize_t amdgpu_get_dpm_forced_performance_level(struct device *dev,
	struct drm_device *ddev = dev_get_drvdata(dev);
	struct amdgpu_device *adev = ddev->dev_private;

	if  ((adev->flags & AMD_IS_PX) &&
	     (ddev->switch_power_state != DRM_SWITCH_POWER_ON))
		return snprintf(buf, PAGE_SIZE, "off\n");

	if (adev->pp_enabled) {
		enum amd_dpm_forced_level level;

@@ -140,6 +144,11 @@ static ssize_t amdgpu_set_dpm_forced_performance_level(struct device *dev,
	enum amdgpu_dpm_forced_level level;
	int ret = 0;

	/* Can't force performance level when the card is off */
	if  ((adev->flags & AMD_IS_PX) &&
	     (ddev->switch_power_state != DRM_SWITCH_POWER_ON))
		return -EINVAL;

	if (strncmp("low", buf, strlen("low")) == 0) {
		level = AMDGPU_DPM_FORCED_LEVEL_LOW;
	} else if (strncmp("high", buf, strlen("high")) == 0) {
@@ -157,6 +166,7 @@ static ssize_t amdgpu_set_dpm_forced_performance_level(struct device *dev,
		mutex_lock(&adev->pm.mutex);
		if (adev->pm.dpm.thermal_active) {
			count = -EINVAL;
			mutex_unlock(&adev->pm.mutex);
			goto fail;
		}
		ret = amdgpu_dpm_force_performance_level(adev, level);
@@ -167,8 +177,6 @@ static ssize_t amdgpu_set_dpm_forced_performance_level(struct device *dev,
		mutex_unlock(&adev->pm.mutex);
	}
fail:
	mutex_unlock(&adev->pm.mutex);

	return count;
}

@@ -182,8 +190,14 @@ static ssize_t amdgpu_hwmon_show_temp(struct device *dev,
				      char *buf)
{
	struct amdgpu_device *adev = dev_get_drvdata(dev);
	struct drm_device *ddev = adev->ddev;
	int temp;

	/* Can't get temperature when the card is off */
	if  ((adev->flags & AMD_IS_PX) &&
	     (ddev->switch_power_state != DRM_SWITCH_POWER_ON))
		return -EINVAL;

	if (!adev->pp_enabled && !adev->pm.funcs->get_temperature)
		temp = 0;
	else
@@ -634,8 +648,6 @@ static void amdgpu_dpm_change_power_state_locked(struct amdgpu_device *adev)

	/* update display watermarks based on new power state */
	amdgpu_display_bandwidth_update(adev);
	/* update displays */
	amdgpu_dpm_display_configuration_changed(adev);

	adev->pm.dpm.current_active_crtcs = adev->pm.dpm.new_active_crtcs;
	adev->pm.dpm.current_active_crtc_count = adev->pm.dpm.new_active_crtc_count;
@@ -655,6 +667,9 @@ static void amdgpu_dpm_change_power_state_locked(struct amdgpu_device *adev)

	amdgpu_dpm_post_set_power_state(adev);

	/* update displays */
	amdgpu_dpm_display_configuration_changed(adev);

	if (adev->pm.funcs->force_performance_level) {
		if (adev->pm.dpm.thermal_active) {
			enum amdgpu_dpm_forced_level level = adev->pm.dpm.forced_level;
@@ -847,12 +862,16 @@ static int amdgpu_debugfs_pm_info(struct seq_file *m, void *data)
	struct drm_info_node *node = (struct drm_info_node *) m->private;
	struct drm_device *dev = node->minor->dev;
	struct amdgpu_device *adev = dev->dev_private;
	struct drm_device *ddev = adev->ddev;

	if (!adev->pm.dpm_enabled) {
		seq_printf(m, "dpm not enabled\n");
		return 0;
	}
	if (adev->pp_enabled) {
	if  ((adev->flags & AMD_IS_PX) &&
	     (ddev->switch_power_state != DRM_SWITCH_POWER_ON)) {
		seq_printf(m, "PX asic powered off\n");
	} else if (adev->pp_enabled) {
		amdgpu_dpm_debugfs_print_current_performance_level(adev, m);
	} else {
		mutex_lock(&adev->pm.mutex);
+1 −1
Original line number Diff line number Diff line
@@ -4995,7 +4995,7 @@ static int gfx_v8_0_set_priv_reg_fault_state(struct amdgpu_device *adev,
	case AMDGPU_IRQ_STATE_ENABLE:
		cp_int_cntl = RREG32(mmCP_INT_CNTL_RING0);
		cp_int_cntl = REG_SET_FIELD(cp_int_cntl, CP_INT_CNTL_RING0,
					    PRIV_REG_INT_ENABLE, 0);
					    PRIV_REG_INT_ENABLE, 1);
		WREG32(mmCP_INT_CNTL_RING0, cp_int_cntl);
		break;
	default:
+2 −2
Original line number Diff line number Diff line
@@ -31,7 +31,7 @@
static int pem_init(struct pp_eventmgr *eventmgr)
{
	int result = 0;
	struct pem_event_data event_data;
	struct pem_event_data event_data = { {0} };

	/* Initialize PowerPlay feature info */
	pem_init_feature_info(eventmgr);
@@ -52,7 +52,7 @@ static int pem_init(struct pp_eventmgr *eventmgr)

static void pem_fini(struct pp_eventmgr *eventmgr)
{
	struct pem_event_data event_data;
	struct pem_event_data event_data = { {0} };

	pem_uninit_featureInfo(eventmgr);
	pem_unregister_interrupts(eventmgr);
Loading